diff --git a/src/csharp/Grpc.Auth/.gitignore b/src/csharp/Grpc.Auth/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..c2dd6641675ac03d8a7e5d6af6f03637ef4cd137
--- /dev/null
+++ b/src/csharp/Grpc.Auth/.gitignore
@@ -0,0 +1,3 @@
+bin
+obj
+*.nupkg
diff --git a/src/csharp/Grpc.Auth/GoogleCredential.cs b/src/csharp/Grpc.Auth/GoogleCredential.cs
new file mode 100644
index 0000000000000000000000000000000000000000..36d43d320714ba63e7b9b59b632a538f5e9b1534
--- /dev/null
+++ b/src/csharp/Grpc.Auth/GoogleCredential.cs
@@ -0,0 +1,124 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Security.Cryptography;
+
+using Google.Apis.Auth.OAuth2;
+using Mono.Security.Cryptography;
+using Newtonsoft.Json.Linq;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Security;
+
+namespace Grpc.Auth
+{
+    // TODO(jtattermusch): Remove this class once possible.
+    /// <summary>
+    /// A temporary placeholder for Google credential from 
+    /// Google Auth library for .NET. It emulates the usage pattern 
+    /// for Usable auth.
+    /// </summary>
+    public class GoogleCredential
+    {
+        private const string GoogleApplicationCredentialsEnvName = "GOOGLE_APPLICATION_CREDENTIALS";
+        private const string ClientEmailFieldName = "client_email";
+        private const string PrivateKeyFieldName = "private_key";
+
+        private ServiceCredential credential;
+
+        private GoogleCredential(ServiceCredential credential)
+        {
+            this.credential = credential;
+        }
+
+        public static GoogleCredential GetApplicationDefault()
+        {
+            return new GoogleCredential(null);  
+        }
+
+        public bool IsCreateScopedRequired
+        {
+            get
+            {
+                return true;
+            }
+        }
+
+        public GoogleCredential CreateScoped(IEnumerable<string> scopes)
+        {
+            var credsPath = Environment.GetEnvironmentVariable(GoogleApplicationCredentialsEnvName);
+            if (credsPath == null)
+            {
+                // Default to ComputeCredentials if path to JSON key is not set.
+                // ComputeCredential is not scoped actually, but for our use case it's
+                // fine to treat is as such.
+                return new GoogleCredential(new ComputeCredential(new ComputeCredential.Initializer()));
+            }
+
+            JObject o1 = JObject.Parse(File.ReadAllText(credsPath));
+            string clientEmail = o1.GetValue(ClientEmailFieldName).Value<string>();
+            string privateKeyString = o1.GetValue(PrivateKeyFieldName).Value<string>();
+            var privateKey = ParsePrivateKeyFromString(privateKeyString);
+
+            var serviceCredential = new ServiceAccountCredential(
+                new ServiceAccountCredential.Initializer(clientEmail)
+                {
+                    Scopes = scopes,
+                    Key = privateKey
+                });
+            return new GoogleCredential(serviceCredential);
+        }
+
+        internal ServiceCredential InternalCredential
+        {
+            get
+            {
+                return credential;
+            }
+        }
+
+        private RSACryptoServiceProvider ParsePrivateKeyFromString(string base64PrivateKey)
+        {
+            // TODO(jtattermusch): temporary code to create RSACryptoServiceProvider.
+            base64PrivateKey = base64PrivateKey.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("\n", "").Replace("-----END PRIVATE KEY-----", "");
+            PKCS8.PrivateKeyInfo PKI = new PKCS8.PrivateKeyInfo(Convert.FromBase64String(base64PrivateKey));
+            RsaPrivateCrtKeyParameters key = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(PKI.GetBytes());
+            RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(key);
+            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
+            rsa.ImportParameters(rsaParameters);
+            return rsa;
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..1931db5fd8fa47b48a615fba55568ec8c811c538
--- /dev/null
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>Grpc.Auth</RootNamespace>
+    <AssemblyName>Grpc.Auth</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="BouncyCastle.Crypto">
+      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth">
+      <HintPath>..\packages\Google.Apis.Auth.1.9.1\lib\net40\Google.Apis.Auth.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth.PlatformServices">
+      <HintPath>..\packages\Google.Apis.Auth.1.9.1\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Core">
+      <HintPath>..\packages\Google.Apis.Core.1.9.1\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Threading.Tasks">
+      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Threading.Tasks.Extensions">
+      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop">
+      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
+    </Reference>
+    <Reference Include="Mono.Security">
+      <HintPath>..\packages\Mono.Security.3.2.3.0\lib\net45\Mono.Security.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Net" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Net.Http.Extensions">
+      <HintPath>..\packages\Microsoft.Net.Http.2.2.28\lib\net45\System.Net.Http.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Net.Http.Primitives">
+      <HintPath>..\packages\Microsoft.Net.Http.2.2.28\lib\net45\System.Net.Http.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Net.Http.WebRequest" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="GoogleCredential.cs" />
+    <Compile Include="OAuth2InterceptorFactory.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
+      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
+      <Name>Grpc.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" />
+  <Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
+    <Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
+    <Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
+  </Target>
+</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Auth/OAuth2InterceptorFactory.cs b/src/csharp/Grpc.Auth/OAuth2InterceptorFactory.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ca384d1a6e444fe2f513fc84289d7d0d8eeefb56
--- /dev/null
+++ b/src/csharp/Grpc.Auth/OAuth2InterceptorFactory.cs
@@ -0,0 +1,104 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Security.Cryptography.X509Certificates;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+
+using Google.Apis.Auth.OAuth2;
+using Google.Apis.Util;
+using Grpc.Core;
+using Grpc.Core.Utils;
+
+namespace Grpc.Auth
+{
+    public static class OAuth2InterceptorFactory
+    {
+        /// <summary>
+        /// Creates OAuth2 interceptor.
+        /// </summary>
+        public static HeaderInterceptorDelegate Create(GoogleCredential googleCredential)
+        {
+            var interceptor = new OAuth2Interceptor(googleCredential.InternalCredential, SystemClock.Default);
+            return new HeaderInterceptorDelegate(interceptor.InterceptHeaders);
+        }
+
+        /// <summary>
+        /// Injects OAuth2 authorization header into initial metadata (= request headers).
+        /// </summary>
+        private class OAuth2Interceptor
+        {
+            private const string AuthorizationHeader = "Authorization";
+            private const string Schema = "Bearer";
+
+            private ServiceCredential credential;
+            private IClock clock;
+
+            public OAuth2Interceptor(ServiceCredential credential, IClock clock)
+            {
+                this.credential = credential;
+                this.clock = clock;
+            }
+
+            /// <summary>
+            /// Gets access token and requests refreshing it if is going to expire soon.
+            /// </summary>
+            /// <param name="cancellationToken"></param>
+            /// <returns></returns>
+            public string GetAccessToken(CancellationToken cancellationToken)
+            {
+                if (credential.Token == null || credential.Token.IsExpired(clock))
+                {
+                    // TODO(jtattermusch): Parallel requests will spawn multiple requests to refresh the token once the token expires.
+                    // TODO(jtattermusch): Rethink synchronous wait to obtain the result.
+                    if (!credential.RequestAccessTokenAsync(cancellationToken).Result)
+                    {
+                        throw new InvalidOperationException("The access token has expired but we can't refresh it");
+                    }
+                }
+                return credential.Token.AccessToken;
+            }
+
+            public void InterceptHeaders(Metadata.Builder headerBuilder)
+            {
+                var accessToken = GetAccessToken(CancellationToken.None);
+                headerBuilder.Add(new Metadata.MetadataEntry(AuthorizationHeader, Schema + " " + accessToken));
+            }
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Auth/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Auth/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000000000000000000000000000000000..66b18d0ccf0dea0d17f903b47430ac657efcffec
--- /dev/null
+++ b/src/csharp/Grpc.Auth/Properties/AssemblyInfo.cs
@@ -0,0 +1,14 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle("Grpc.Auth")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Google Inc.  All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: AssemblyVersion("0.2.*")]
+
+[assembly: InternalsVisibleTo("Grpc.Auth.Tests")]
\ No newline at end of file
diff --git a/src/csharp/Grpc.Auth/app.config b/src/csharp/Grpc.Auth/app.config
new file mode 100644
index 0000000000000000000000000000000000000000..966b777192f3d53ea95e7056f903c1bc009213f8
--- /dev/null
+++ b/src/csharp/Grpc.Auth/app.config
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.2.28.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.0.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Auth/packages.config b/src/csharp/Grpc.Auth/packages.config
new file mode 100644
index 0000000000000000000000000000000000000000..0816bdbad15fff474698ef62497b930d8ebfa555
--- /dev/null
+++ b/src/csharp/Grpc.Auth/packages.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.9.1" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.9.1" targetFramework="net45" />
+  <package id="Microsoft.Bcl" version="1.1.9" targetFramework="net45" />
+  <package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
+  <package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net45" />
+  <package id="Microsoft.Net.Http" version="2.2.28" targetFramework="net45" />
+  <package id="Mono.Security" version="3.2.3.0" targetFramework="net45" />
+  <package id="Newtonsoft.Json" version="6.0.6" targetFramework="net45" />
+</packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index b612512b03c1257249192e37452351c394ade422..0b85392e15a9d54ca936ff432b61273e2da50ed5 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -34,8 +34,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="System" />
-    <Reference Include="System.Collections.Immutable, Version=1.0.34.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
+    <Reference Include="System.Collections.Immutable">
       <HintPath>..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
     </Reference>
   </ItemGroup>
diff --git a/src/csharp/Grpc.Core/RpcException.cs b/src/csharp/Grpc.Core/RpcException.cs
index 433d87215ee3f4b6151ce020ff8c7f4ed5840508..c58578286b3e886cc3f950e8fd07dfb3d0ae4e4a 100644
--- a/src/csharp/Grpc.Core/RpcException.cs
+++ b/src/csharp/Grpc.Core/RpcException.cs
@@ -42,7 +42,7 @@ namespace Grpc.Core
     {
         private readonly Status status;
 
-        public RpcException(Status status)
+        public RpcException(Status status) : base(status.ToString())
         {
             this.status = status;
         }
diff --git a/src/csharp/Grpc.Core/Status.cs b/src/csharp/Grpc.Core/Status.cs
index 080bbdc2f5b3544b5917126837490732ae1a3f9f..7d76aec4d1198dda8969c79cede6ff0dbe3e556b 100644
--- a/src/csharp/Grpc.Core/Status.cs
+++ b/src/csharp/Grpc.Core/Status.cs
@@ -69,5 +69,10 @@ namespace Grpc.Core
                 return detail;
             }
         }
+
+        public override string ToString()
+        {
+            return string.Format("Status(StatusCode={0}, Detail=\"{1}\")", statusCode, detail);
+        }
     }
 }
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
index b1a4a81916a25eca2993f9ed715ceb53cd493410..df05c535e2472636515ebb270c3fc89fe79a2fc0 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -46,4 +46,7 @@
       <Name>Grpc.IntegrationTesting</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+  </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/app.config b/src/csharp/Grpc.IntegrationTesting.Client/app.config
new file mode 100644
index 0000000000000000000000000000000000000000..966b777192f3d53ea95e7056f903c1bc009213f8
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.Client/app.config
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.2.28.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.0.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
index 73c9f2d2077ae36f1cf33adaa6b3b9aedca871b1..235897c888e6e483eabd732c99c707b6940c8446 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -46,4 +46,7 @@
       <Name>Grpc.IntegrationTesting</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+  </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/app.config b/src/csharp/Grpc.IntegrationTesting.Server/app.config
new file mode 100644
index 0000000000000000000000000000000000000000..966b777192f3d53ea95e7056f903c1bc009213f8
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.Server/app.config
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.2.28.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.0.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index 6ae8041fb7cdddd9ccfc0d430fd14daad9310c08..13bbb5363fa41ad8e9837e7ce9863af628d92d7c 100644
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -32,6 +32,21 @@
     <PlatformTarget>x86</PlatformTarget>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="Google.Apis.Auth.PlatformServices">
+      <HintPath>..\packages\Google.Apis.Auth.1.9.1\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Core">
+      <HintPath>..\packages\Google.Apis.Core.1.9.1\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Threading.Tasks">
+      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Threading.Tasks.Extensions">
+      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop">
+      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
+    </Reference>
     <Reference Include="nunit.framework">
       <HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
     </Reference>
@@ -39,8 +54,19 @@
     <Reference Include="Google.ProtocolBuffers">
       <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.521\lib\net40\Google.ProtocolBuffers.dll</HintPath>
     </Reference>
-    <Reference Include="System.Collections.Immutable, Version=1.0.34.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
+    <Reference Include="System.Net" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Net.Http.Extensions">
+      <HintPath>..\packages\Microsoft.Net.Http.2.2.28\lib\net45\System.Net.Http.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Net.Http.Primitives">
+      <HintPath>..\packages\Microsoft.Net.Http.2.2.28\lib\net45\System.Net.Http.Primitives.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Net.Http.WebRequest" />
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Collections.Immutable">
       <HintPath>..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
     </Reference>
   </ItemGroup>
@@ -61,8 +87,13 @@
       <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
       <Name>Grpc.Core</Name>
     </ProjectReference>
+    <ProjectReference Include="..\Grpc.Auth\Grpc.Auth.csproj">
+      <Project>{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}</Project>
+      <Name>Grpc.Auth</Name>
+    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
+    <None Include="app.config" />
     <None Include="packages.config" />
     <None Include="proto\test.proto" />
     <None Include="proto\empty.proto" />
@@ -83,4 +114,9 @@
   <ItemGroup>
     <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
   </ItemGroup>
+  <Import Project="..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" />
+  <Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
+    <Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
+    <Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
+  </Target>
 </Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index 6b92d3c660fe56737661b551f40527ee32d68949..1fbae374b1d61372f48371b197a81fbbb797280b 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -33,12 +33,11 @@
 
 using System;
 using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
 using System.Text.RegularExpressions;
-using System.Threading.Tasks;
+
 using Google.ProtocolBuffers;
 using grpc.testing;
+using Grpc.Auth;
 using Grpc.Core;
 using Grpc.Core.Utils;
 using NUnit.Framework;
@@ -47,6 +46,11 @@ namespace Grpc.IntegrationTesting
 {
     public class InteropClient
     {
+        private const string ServiceAccountUser = "155450119199-3psnrh1sdr3d8cpj1v46naggf81mhdnk@developer.gserviceaccount.com";
+        private const string ComputeEngineUser = "155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel@developer.gserviceaccount.com";
+        private const string AuthScope = "https://www.googleapis.com/auth/xapi.zoo";
+        private const string AuthScopeResponse = "xapi.zoo";
+
         private class ClientOptions
         {
             public bool help;
@@ -115,7 +119,18 @@ namespace Grpc.IntegrationTesting
 
             using (Channel channel = new Channel(addr, credentials, channelArgs))
             {
-                TestServiceGrpc.ITestServiceClient client = new TestServiceGrpc.TestServiceClientStub(channel);
+                var stubConfig = StubConfiguration.Default;
+                if (options.testCase == "service_account_creds" || options.testCase == "compute_engine_creds")
+                {
+                    var credential = GoogleCredential.GetApplicationDefault();
+                    if (credential.IsCreateScopedRequired)
+                    {
+                        credential = credential.CreateScoped(new[] { AuthScope });
+                    }
+                    stubConfig = new StubConfiguration(OAuth2InterceptorFactory.Create(credential));
+                }
+
+                TestServiceGrpc.ITestServiceClient client = new TestServiceGrpc.TestServiceClientStub(channel, stubConfig);
                 RunTestCase(options.testCase, client);
             }
 
@@ -144,6 +159,12 @@ namespace Grpc.IntegrationTesting
                 case "empty_stream":
                     RunEmptyStream(client);
                     break;
+                case "service_account_creds":
+                    RunServiceAccountCreds(client);
+                    break;
+                case "compute_engine_creds":
+                    RunComputeEngineCreds(client);
+                    break;
                 case "benchmark_empty_unary":
                     RunBenchmarkEmptyUnary(client);
                     break;
@@ -287,6 +308,46 @@ namespace Grpc.IntegrationTesting
             Console.WriteLine("Passed!");
         }
 
+        public static void RunServiceAccountCreds(TestServiceGrpc.ITestServiceClient client)
+        {
+            Console.WriteLine("running service_account_creds");
+            var request = SimpleRequest.CreateBuilder()
+                .SetResponseType(PayloadType.COMPRESSABLE)
+                    .SetResponseSize(314159)
+                    .SetPayload(CreateZerosPayload(271828))
+                    .SetFillUsername(true)
+                    .SetFillOauthScope(true)
+                    .Build();
+
+            var response = client.UnaryCall(request);
+
+            Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
+            Assert.AreEqual(314159, response.Payload.Body.Length);
+            Assert.AreEqual(AuthScopeResponse, response.OauthScope);
+            Assert.AreEqual(ServiceAccountUser, response.Username);
+            Console.WriteLine("Passed!");
+        }
+
+        public static void RunComputeEngineCreds(TestServiceGrpc.ITestServiceClient client)
+        {
+            Console.WriteLine("running compute_engine_creds");
+            var request = SimpleRequest.CreateBuilder()
+                .SetResponseType(PayloadType.COMPRESSABLE)
+                    .SetResponseSize(314159)
+                    .SetPayload(CreateZerosPayload(271828))
+                    .SetFillUsername(true)
+                    .SetFillOauthScope(true)
+                    .Build();
+
+            var response = client.UnaryCall(request);
+
+            Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
+            Assert.AreEqual(314159, response.Payload.Body.Length);
+            Assert.AreEqual(AuthScopeResponse, response.OauthScope);
+            Assert.AreEqual(ComputeEngineUser, response.Username);
+            Console.WriteLine("Passed!");
+        }
+
         // This is not an official interop test, but it's useful.
         public static void RunBenchmarkEmptyUnary(TestServiceGrpc.ITestServiceClient client)
         {
diff --git a/src/csharp/Grpc.IntegrationTesting/app.config b/src/csharp/Grpc.IntegrationTesting/app.config
new file mode 100644
index 0000000000000000000000000000000000000000..966b777192f3d53ea95e7056f903c1bc009213f8
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/app.config
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.2.28.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.0.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+</configuration>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config
index 335f829432d294df41ab545f93a46e22ae433e9a..e33b6e3e464119fedd1e83ebc41ca19958cb8a00 100644
--- a/src/csharp/Grpc.IntegrationTesting/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting/packages.config
@@ -1,6 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
+  <package id="Google.Apis.Auth" version="1.9.1" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.9.1" targetFramework="net45" />
   <package id="Google.ProtocolBuffers" version="2.4.1.521" targetFramework="net45" />
+  <package id="Microsoft.Bcl" version="1.1.9" targetFramework="net45" />
+  <package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
+  <package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net45" />
   <package id="Microsoft.Bcl.Immutable" version="1.0.34" targetFramework="net45" />
+  <package id="Microsoft.Net.Http" version="2.2.28" targetFramework="net45" />
+  <package id="Newtonsoft.Json" version="6.0.6" targetFramework="net45" />
   <package id="NUnit" version="2.6.4" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln
index 2f8c2e171902df02599f5d95335c1d401657907c..e2a374e362a4afc38db8de6a7bff84ce4d469243 100644
--- a/src/csharp/Grpc.sln
+++ b/src/csharp/Grpc.sln
@@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Ser
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Examples.MathServer", "Grpc.Examples.MathServer\Grpc.Examples.MathServer.csproj", "{BF62FE08-373A-43D6-9D73-41CAA38B7011}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Auth", "Grpc.Auth\Grpc.Auth.csproj", "{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|x86 = Debug|x86
@@ -49,6 +51,10 @@ Global
 		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|x86.Build.0 = Debug|x86
 		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|x86.ActiveCfg = Release|x86
 		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|x86.Build.0 = Release|x86
+		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Debug|x86.Build.0 = Debug|Any CPU
+		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Release|x86.ActiveCfg = Release|Any CPU
+		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Release|x86.Build.0 = Release|Any CPU
 		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|x86.ActiveCfg = Debug|x86
 		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|x86.Build.0 = Debug|x86
 		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|x86.ActiveCfg = Release|x86