diff --git a/include/grpc++/credentials.h b/include/grpc++/credentials.h
index b462b450dafad9bf1a2d0fa3fa48d02fe520f5f1..26e9b556fe4ca34defb8513f47b346cae420b279 100644
--- a/include/grpc++/credentials.h
+++ b/include/grpc++/credentials.h
@@ -42,11 +42,19 @@
 namespace grpc {
 class ChannelArguments;
 class ChannelInterface;
+class SecureCredentials;
 
 class Credentials {
  public:
   virtual ~Credentials();
 
+ protected:
+  friend std::unique_ptr<Credentials> ComposeCredentials(
+    const std::unique_ptr<Credentials>& creds1,
+    const std::unique_ptr<Credentials>& creds2);
+
+  virtual SecureCredentials* AsSecureCredentials() = 0;
+
  private:
   friend std::shared_ptr<ChannelInterface> CreateChannel(
       const grpc::string& target, const std::unique_ptr<Credentials>& creds,
diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc
index 4f3bba5c8e523179230c7acf7f396a5501098df6..8180d1e60ed76c6140b2b904f774b2af9459ac01 100644
--- a/src/cpp/client/insecure_credentials.cc
+++ b/src/cpp/client/insecure_credentials.cc
@@ -50,6 +50,8 @@ class InsecureCredentialsImpl final : public Credentials {
     args.SetChannelArgs(&channel_args);
     return std::shared_ptr<ChannelInterface>(new Channel(target, grpc_channel_create(target.c_str(), &channel_args)));
   }
+
+  SecureCredentials* AsSecureCredentials() { return nullptr; }
 };
 }  // namespace
 
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index 367dfe3447b2311dc099768172e567272fe4702b..f864380105435b06cb00c8bdb9da45bc0e7a0766 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -42,7 +42,6 @@
 
 namespace grpc {
 
-namespace {
 class SecureCredentials final : public Credentials {
  public:
   explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {}
@@ -58,10 +57,15 @@ class SecureCredentials final : public Credentials {
         grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)));
   }
 
+  SecureCredentials* AsSecureCredentials() {
+    return this;
+  }
+
  private:
   grpc_credentials* const c_creds_;
 };
 
+namespace {
 std::unique_ptr<Credentials> WrapCredentials(grpc_credentials* creds) {
   return creds == nullptr
              ? nullptr
@@ -116,8 +120,8 @@ std::unique_ptr<Credentials> ComposeCredentials(
   // passed in here. This is OK because the underlying C objects (i.e.,
   // creds1 and creds2) into grpc_composite_credentials_create will see their
   // refcounts incremented.
-  SecureCredentials* s1 = dynamic_cast<SecureCredentials*>(creds1.get());
-  SecureCredentials* s2 = dynamic_cast<SecureCredentials*>(creds2.get());
+  SecureCredentials* s1 = creds1->AsSecureCredentials();
+  SecureCredentials* s2 = creds2->AsSecureCredentials();
   if (s1 && s2) {
     return WrapCredentials(grpc_composite_credentials_create(
         s1->GetRawCreds(), s2->GetRawCreds()));