diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index cb2537fe98d4308d6fb9554b4ce649208eaf238f..f9f7d5bb39ddf000bada51ed8d300356d90d795f 100755
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -39,6 +39,7 @@ namespace Grpc;
  */
 class BaseStub {
 
+  private $hostname;
   private $channel;
 
   // a callback function
@@ -51,6 +52,7 @@ class BaseStub {
    * metadata array, and returns an updated metadata array
    */
   public function __construct($hostname, $opts) {
+    $this->hostname = $hostname;
     $this->update_metadata = null;
     if (isset($opts['update_metadata'])) {
       if (is_callable($opts['update_metadata'])) {
@@ -69,6 +71,15 @@ class BaseStub {
     $channel->close();
   }
 
+  private function _get_jwt_aud_uri($method) {
+    $last_slash_idx = strrpos($method, '/');
+    if ($last_slash_idx === false) {
+      return false;
+    }
+    $service_name = substr($method, 0, $last_slash_idx);
+    return "https://" . $this->hostname . $service_name;
+  }
+
   /* This class is intended to be subclassed by generated code, so all functions
      begin with "_" to avoid name collisions. */
 
@@ -87,9 +98,11 @@ class BaseStub {
                                  $metadata = array()) {
     $call = new UnaryCall($this->channel, $method, $deserialize);
     $actual_metadata = $metadata;
+    $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
     if (is_callable($this->update_metadata)) {
       $actual_metadata = call_user_func($this->update_metadata,
-                                        $actual_metadata);
+                                        $actual_metadata,
+                                        $jwt_aud_uri);
     }
     $call->start($argument, $actual_metadata);
     return $call;
@@ -112,9 +125,11 @@ class BaseStub {
                                        $metadata = array()) {
     $call = new ClientStreamingCall($this->channel, $method, $deserialize);
     $actual_metadata = $metadata;
+    $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
     if (is_callable($this->update_metadata)) {
       $actual_metadata = call_user_func($this->update_metadata,
-                                        $actual_metadata);
+                                        $actual_metadata,
+                                        $jwt_aud_uri);
     }
     $call->start($arguments, $actual_metadata);
     return $call;
@@ -136,9 +151,11 @@ class BaseStub {
                                        $metadata = array()) {
     $call = new ServerStreamingCall($this->channel, $method, $deserialize);
     $actual_metadata = $metadata;
+    $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
     if (is_callable($this->update_metadata)) {
       $actual_metadata = call_user_func($this->update_metadata,
-                                        $actual_metadata);
+                                        $actual_metadata,
+                                        $jwt_aud_uri);
     }
     $call->start($argument, $actual_metadata);
     return $call;
@@ -157,9 +174,11 @@ class BaseStub {
                                $metadata = array()) {
     $call = new BidiStreamingCall($this->channel, $method, $deserialize);
     $actual_metadata = $metadata;
+    $jwt_aud_uri = $this->_get_jwt_aud_uri($method);
     if (is_callable($this->update_metadata)) {
       $actual_metadata = call_user_func($this->update_metadata,
-                                        $actual_metadata);
+                                        $actual_metadata,
+                                        $jwt_aud_uri);
     }
     $call->start($actual_metadata);
     return $call;
diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php
index 98a367a905caa5ca4c8e592390c1ea940967a3aa..bf8d0cd93ce2454bece8e144ddd956b3628255b9 100755
--- a/src/php/tests/interop/interop_client.php
+++ b/src/php/tests/interop/interop_client.php
@@ -143,6 +143,21 @@ function computeEngineCreds($stub, $args) {
              'invalid email returned');
 }
 
+/**
+ * Run the jwt token credentials auth test.
+ * Passes when run against the cloud server as of 2015-05-12
+ * @param $stub Stub object that has service methods
+ * @param $args array command line args
+ */
+function jwtTokenCreds($stub, $args) {
+  $jsonKey = json_decode(
+      file_get_contents(getenv(Google\Auth\CredentialsLoader::ENV_VAR)),
+      true);
+  $result = performLargeUnary($stub, $fillUsername=true, $fillOauthScope=true);
+  hardAssert($result->getUsername() == $jsonKey['client_email'],
+             'invalid email returned');
+}
+
 /**
  * Run the client_streaming test.
  * Passes when run against the Node server as of 2015-04-30
@@ -266,7 +281,11 @@ if (!array_key_exists('server_host', $args) ||
   throw new Exception('Missing argument');
 }
 
-$server_address = $args['server_host'] . ':' . $args['server_port'];
+if ($args['server_port'] == 443) {
+  $server_address = $args['server_host'];
+} else {
+  $server_address = $args['server_host'] . ':' . $args['server_port'];
+}
 
 if (!array_key_exists('server_host_override', $args)) {
   $args['server_host_override'] = 'foo.test.google.fr';
@@ -284,9 +303,16 @@ $opts = [
     'credentials' => $credentials,
          ];
 
-if (array_key_exists('oauth_scope', $args)) {
-  $auth = Google\Auth\ApplicationDefaultCredentials::getCredentials(
+if (in_array($args['test_case'], array(
+      'service_account_creds',
+      'compute_engine_creds',
+      'jwt_token_creds'))) {
+  if ($args['test_case'] == 'jwt_token_creds') {
+    $auth = Google\Auth\ApplicationDefaultCredentials::getCredentials();
+  } else {
+    $auth = Google\Auth\ApplicationDefaultCredentials::getCredentials(
       $args['oauth_scope']);
+  }
   $opts['update_metadata'] = $auth->getUpdateMetadataFunc();
 }
 
@@ -323,6 +349,9 @@ switch ($args['test_case']) {
   case 'compute_engine_creds':
     computeEngineCreds($stub, $args);
     break;
+  case 'jwt_token_creds':
+    jwtTokenCreds($stub, $args);
+    break;
   default:
     exit(1);
 }