Refactoring of core security to remove the factories.

- Renamed security_context -> security_connector.
- Credentials are now responsible for creating their own connectors.
diff --git a/BUILD b/BUILD
index 916f24e..8bebe1b 100644
--- a/BUILD
+++ b/BUILD
@@ -124,7 +124,7 @@
   srcs = [
     "src/core/httpcli/format_request.h",
     "src/core/httpcli/httpcli.h",
-    "src/core/httpcli/httpcli_security_context.h",
+    "src/core/httpcli/httpcli_security_connector.h",
     "src/core/httpcli/parser.h",
     "src/core/security/auth.h",
     "src/core/security/base64.h",
@@ -132,7 +132,7 @@
     "src/core/security/json_token.h",
     "src/core/security/secure_endpoint.h",
     "src/core/security/secure_transport_setup.h",
-    "src/core/security/security_context.h",
+    "src/core/security/security_connector.h",
     "src/core/tsi/fake_transport_security.h",
     "src/core/tsi/ssl_transport_security.h",
     "src/core/tsi/transport_security.h",
@@ -228,19 +228,18 @@
     "src/core/transport/transport_impl.h",
     "src/core/httpcli/format_request.c",
     "src/core/httpcli/httpcli.c",
-    "src/core/httpcli/httpcli_security_context.c",
+    "src/core/httpcli/httpcli_security_connector.c",
     "src/core/httpcli/parser.c",
     "src/core/security/auth.c",
     "src/core/security/base64.c",
     "src/core/security/credentials.c",
     "src/core/security/credentials_posix.c",
     "src/core/security/credentials_win32.c",
-    "src/core/security/factories.c",
     "src/core/security/google_default_credentials.c",
     "src/core/security/json_token.c",
     "src/core/security/secure_endpoint.c",
     "src/core/security/secure_transport_setup.c",
-    "src/core/security/security_context.c",
+    "src/core/security/security_connector.c",
     "src/core/security/server_secure_chttp2.c",
     "src/core/surface/init_secure.c",
     "src/core/surface/secure_channel_create.c",
diff --git a/Makefile b/Makefile
index e3204fc..4a8ab16 100644
--- a/Makefile
+++ b/Makefile
@@ -2591,19 +2591,18 @@
 LIBGRPC_SRC = \
     src/core/httpcli/format_request.c \
     src/core/httpcli/httpcli.c \
-    src/core/httpcli/httpcli_security_context.c \
+    src/core/httpcli/httpcli_security_connector.c \
     src/core/httpcli/parser.c \
     src/core/security/auth.c \
     src/core/security/base64.c \
     src/core/security/credentials.c \
     src/core/security/credentials_posix.c \
     src/core/security/credentials_win32.c \
-    src/core/security/factories.c \
     src/core/security/google_default_credentials.c \
     src/core/security/json_token.c \
     src/core/security/secure_endpoint.c \
     src/core/security/secure_transport_setup.c \
-    src/core/security/security_context.c \
+    src/core/security/security_connector.c \
     src/core/security/server_secure_chttp2.c \
     src/core/surface/init_secure.c \
     src/core/surface/secure_channel_create.c \
@@ -2740,19 +2739,18 @@
 # otherwise parallel compilation will fail if a source is compiled first.
 src/core/httpcli/format_request.c: $(OPENSSL_DEP)
 src/core/httpcli/httpcli.c: $(OPENSSL_DEP)
-src/core/httpcli/httpcli_security_context.c: $(OPENSSL_DEP)
+src/core/httpcli/httpcli_security_connector.c: $(OPENSSL_DEP)
 src/core/httpcli/parser.c: $(OPENSSL_DEP)
 src/core/security/auth.c: $(OPENSSL_DEP)
 src/core/security/base64.c: $(OPENSSL_DEP)
 src/core/security/credentials.c: $(OPENSSL_DEP)
 src/core/security/credentials_posix.c: $(OPENSSL_DEP)
 src/core/security/credentials_win32.c: $(OPENSSL_DEP)
-src/core/security/factories.c: $(OPENSSL_DEP)
 src/core/security/google_default_credentials.c: $(OPENSSL_DEP)
 src/core/security/json_token.c: $(OPENSSL_DEP)
 src/core/security/secure_endpoint.c: $(OPENSSL_DEP)
 src/core/security/secure_transport_setup.c: $(OPENSSL_DEP)
-src/core/security/security_context.c: $(OPENSSL_DEP)
+src/core/security/security_connector.c: $(OPENSSL_DEP)
 src/core/security/server_secure_chttp2.c: $(OPENSSL_DEP)
 src/core/surface/init_secure.c: $(OPENSSL_DEP)
 src/core/surface/secure_channel_create.c: $(OPENSSL_DEP)
@@ -2905,19 +2903,18 @@
 
 $(OBJDIR)/$(CONFIG)/src/core/httpcli/format_request.o: 
 $(OBJDIR)/$(CONFIG)/src/core/httpcli/httpcli.o: 
-$(OBJDIR)/$(CONFIG)/src/core/httpcli/httpcli_security_context.o: 
+$(OBJDIR)/$(CONFIG)/src/core/httpcli/httpcli_security_connector.o: 
 $(OBJDIR)/$(CONFIG)/src/core/httpcli/parser.o: 
 $(OBJDIR)/$(CONFIG)/src/core/security/auth.o: 
 $(OBJDIR)/$(CONFIG)/src/core/security/base64.o: 
 $(OBJDIR)/$(CONFIG)/src/core/security/credentials.o: 
 $(OBJDIR)/$(CONFIG)/src/core/security/credentials_posix.o: 
 $(OBJDIR)/$(CONFIG)/src/core/security/credentials_win32.o: 
-$(OBJDIR)/$(CONFIG)/src/core/security/factories.o: 
 $(OBJDIR)/$(CONFIG)/src/core/security/google_default_credentials.o: 
 $(OBJDIR)/$(CONFIG)/src/core/security/json_token.o: 
 $(OBJDIR)/$(CONFIG)/src/core/security/secure_endpoint.o: 
 $(OBJDIR)/$(CONFIG)/src/core/security/secure_transport_setup.o: 
-$(OBJDIR)/$(CONFIG)/src/core/security/security_context.o: 
+$(OBJDIR)/$(CONFIG)/src/core/security/security_connector.o: 
 $(OBJDIR)/$(CONFIG)/src/core/security/server_secure_chttp2.o: 
 $(OBJDIR)/$(CONFIG)/src/core/surface/init_secure.o: 
 $(OBJDIR)/$(CONFIG)/src/core/surface/secure_channel_create.o: 
diff --git a/build.json b/build.json
index 58837e2..e74fa64 100644
--- a/build.json
+++ b/build.json
@@ -386,7 +386,7 @@
       "headers": [
         "src/core/httpcli/format_request.h",
         "src/core/httpcli/httpcli.h",
-        "src/core/httpcli/httpcli_security_context.h",
+        "src/core/httpcli/httpcli_security_connector.h",
         "src/core/httpcli/parser.h",
         "src/core/security/auth.h",
         "src/core/security/base64.h",
@@ -394,7 +394,7 @@
         "src/core/security/json_token.h",
         "src/core/security/secure_endpoint.h",
         "src/core/security/secure_transport_setup.h",
-        "src/core/security/security_context.h",
+        "src/core/security/security_connector.h",
         "src/core/tsi/fake_transport_security.h",
         "src/core/tsi/ssl_transport_security.h",
         "src/core/tsi/transport_security.h",
@@ -403,19 +403,18 @@
       "src": [
         "src/core/httpcli/format_request.c",
         "src/core/httpcli/httpcli.c",
-        "src/core/httpcli/httpcli_security_context.c",
+        "src/core/httpcli/httpcli_security_connector.c",
         "src/core/httpcli/parser.c",
         "src/core/security/auth.c",
         "src/core/security/base64.c",
         "src/core/security/credentials.c",
         "src/core/security/credentials_posix.c",
         "src/core/security/credentials_win32.c",
-        "src/core/security/factories.c",
         "src/core/security/google_default_credentials.c",
         "src/core/security/json_token.c",
         "src/core/security/secure_endpoint.c",
         "src/core/security/secure_transport_setup.c",
-        "src/core/security/security_context.c",
+        "src/core/security/security_connector.c",
         "src/core/security/server_secure_chttp2.c",
         "src/core/surface/init_secure.c",
         "src/core/surface/secure_channel_create.c",
diff --git a/src/core/httpcli/httpcli.c b/src/core/httpcli/httpcli.c
index d2cf09a..fe7ea6a 100644
--- a/src/core/httpcli/httpcli.c
+++ b/src/core/httpcli/httpcli.c
@@ -40,9 +40,8 @@
 #include "src/core/iomgr/resolve_address.h"
 #include "src/core/iomgr/tcp_client.h"
 #include "src/core/httpcli/format_request.h"
-#include "src/core/httpcli/httpcli_security_context.h"
+#include "src/core/httpcli/httpcli_security_connector.h"
 #include "src/core/httpcli/parser.h"
-#include "src/core/security/security_context.h"
 #include "src/core/security/secure_transport_setup.h"
 #include "src/core/support/string.h"
 #include <grpc/support/alloc.h>
@@ -180,7 +179,7 @@
   }
   req->ep = tcp;
   if (req->use_ssl) {
-    grpc_channel_security_context *ctx = NULL;
+    grpc_channel_security_connector *sc = NULL;
     const unsigned char *pem_root_certs = NULL;
     size_t pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs);
     if (pem_root_certs == NULL || pem_root_certs_size == 0) {
@@ -188,12 +187,12 @@
       finish(req, 0);
       return;
     }
-    GPR_ASSERT(grpc_httpcli_ssl_channel_security_context_create(
-                   pem_root_certs, pem_root_certs_size, req->host, &ctx) ==
+    GPR_ASSERT(grpc_httpcli_ssl_channel_security_connector_create(
+                   pem_root_certs, pem_root_certs_size, req->host, &sc) ==
                GRPC_SECURITY_OK);
-    grpc_setup_secure_transport(&ctx->base, tcp, on_secure_transport_setup_done,
+    grpc_setup_secure_transport(&sc->base, tcp, on_secure_transport_setup_done,
                                 req);
-    grpc_security_context_unref(&ctx->base);
+    grpc_security_connector_unref(&sc->base);
   } else {
     start_write(req);
   }
diff --git a/src/core/httpcli/httpcli_security_context.c b/src/core/httpcli/httpcli_security_connector.c
similarity index 79%
rename from src/core/httpcli/httpcli_security_context.c
rename to src/core/httpcli/httpcli_security_connector.c
index e97752b..6eed5ea 100644
--- a/src/core/httpcli/httpcli_security_context.c
+++ b/src/core/httpcli/httpcli_security_connector.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/httpcli/httpcli_security_context.h"
+#include "src/core/httpcli/httpcli_security_connector.h"
 
 #include <string.h>
 
@@ -42,25 +42,25 @@
 #include "src/core/tsi/ssl_transport_security.h"
 
 typedef struct {
-  grpc_channel_security_context base;
+  grpc_channel_security_connector base;
   tsi_ssl_handshaker_factory *handshaker_factory;
   char *secure_peer_name;
-} grpc_httpcli_ssl_channel_security_context;
+} grpc_httpcli_ssl_channel_security_connector;
 
-static void httpcli_ssl_destroy(grpc_security_context *ctx) {
-  grpc_httpcli_ssl_channel_security_context *c =
-      (grpc_httpcli_ssl_channel_security_context *)ctx;
+static void httpcli_ssl_destroy(grpc_security_connector *sc) {
+  grpc_httpcli_ssl_channel_security_connector *c =
+      (grpc_httpcli_ssl_channel_security_connector *)sc;
   if (c->handshaker_factory != NULL) {
     tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
   }
   if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name);
-  gpr_free(ctx);
+  gpr_free(sc);
 }
 
 static grpc_security_status httpcli_ssl_create_handshaker(
-    grpc_security_context *ctx, tsi_handshaker **handshaker) {
-  grpc_httpcli_ssl_channel_security_context *c =
-      (grpc_httpcli_ssl_channel_security_context *)ctx;
+    grpc_security_connector *sc, tsi_handshaker **handshaker) {
+  grpc_httpcli_ssl_channel_security_connector *c =
+      (grpc_httpcli_ssl_channel_security_connector *)sc;
   tsi_result result = TSI_OK;
   if (c->handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
   result = tsi_ssl_handshaker_factory_create_handshaker(
@@ -73,12 +73,12 @@
   return GRPC_SECURITY_OK;
 }
 
-static grpc_security_status httpcli_ssl_check_peer(grpc_security_context *ctx,
+static grpc_security_status httpcli_ssl_check_peer(grpc_security_connector *sc,
                                                    tsi_peer peer,
                                                    grpc_security_check_cb cb,
                                                    void *user_data) {
-  grpc_httpcli_ssl_channel_security_context *c =
-      (grpc_httpcli_ssl_channel_security_context *)ctx;
+  grpc_httpcli_ssl_channel_security_connector *c =
+      (grpc_httpcli_ssl_channel_security_connector *)sc;
   grpc_security_status status = GRPC_SECURITY_OK;
 
   /* Check the peer name. */
@@ -92,14 +92,14 @@
   return status;
 }
 
-static grpc_security_context_vtable httpcli_ssl_vtable = {
+static grpc_security_connector_vtable httpcli_ssl_vtable = {
     httpcli_ssl_destroy, httpcli_ssl_create_handshaker, httpcli_ssl_check_peer};
 
-grpc_security_status grpc_httpcli_ssl_channel_security_context_create(
+grpc_security_status grpc_httpcli_ssl_channel_security_connector_create(
     const unsigned char *pem_root_certs, size_t pem_root_certs_size,
-    const char *secure_peer_name, grpc_channel_security_context **ctx) {
+    const char *secure_peer_name, grpc_channel_security_connector **sc) {
   tsi_result result = TSI_OK;
-  grpc_httpcli_ssl_channel_security_context *c;
+  grpc_httpcli_ssl_channel_security_connector *c;
 
   if (secure_peer_name != NULL && pem_root_certs == NULL) {
     gpr_log(GPR_ERROR,
@@ -107,8 +107,8 @@
     return GRPC_SECURITY_ERROR;
   }
 
-  c = gpr_malloc(sizeof(grpc_httpcli_ssl_channel_security_context));
-  memset(c, 0, sizeof(grpc_httpcli_ssl_channel_security_context));
+  c = gpr_malloc(sizeof(grpc_httpcli_ssl_channel_security_connector));
+  memset(c, 0, sizeof(grpc_httpcli_ssl_channel_security_connector));
 
   gpr_ref_init(&c->base.base.refcount, 1);
   c->base.base.is_client_side = 1;
@@ -123,9 +123,9 @@
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
     httpcli_ssl_destroy(&c->base.base);
-    *ctx = NULL;
+    *sc = NULL;
     return GRPC_SECURITY_ERROR;
   }
-  *ctx = &c->base;
+  *sc = &c->base;
   return GRPC_SECURITY_OK;
 }
diff --git a/src/core/httpcli/httpcli_security_context.h b/src/core/httpcli/httpcli_security_connector.h
similarity index 80%
rename from src/core/httpcli/httpcli_security_context.h
rename to src/core/httpcli/httpcli_security_connector.h
index a776828..c50f259 100644
--- a/src/core/httpcli/httpcli_security_context.h
+++ b/src/core/httpcli/httpcli_security_connector.h
@@ -31,13 +31,13 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H
-#define GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H
+#ifndef GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONNECTOR_H
+#define GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONNECTOR_H
 
-#include "src/core/security/security_context.h"
+#include "src/core/security/security_connector.h"
 
-grpc_security_status grpc_httpcli_ssl_channel_security_context_create(
+grpc_security_status grpc_httpcli_ssl_channel_security_connector_create(
     const unsigned char *pem_root_certs, size_t pem_root_certs_size,
-    const char *secure_peer_name, grpc_channel_security_context **ctx);
+    const char *secure_peer_name, grpc_channel_security_connector **sc);
 
-#endif  /* GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H */
+#endif  /* GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONNECTOR_H */
diff --git a/src/core/security/auth.c b/src/core/security/auth.c
index 5fc6d27..130698c 100644
--- a/src/core/security/auth.c
+++ b/src/core/security/auth.c
@@ -40,7 +40,7 @@
 
 #include "src/core/support/string.h"
 #include "src/core/channel/channel_stack.h"
-#include "src/core/security/security_context.h"
+#include "src/core/security/security_connector.h"
 #include "src/core/security/credentials.h"
 #include "src/core/surface/call.h"
 
@@ -54,7 +54,7 @@
 
 /* We can have a per-channel credentials. */
 typedef struct {
-  grpc_channel_security_context *security_context;
+  grpc_channel_security_connector *security_connector;
   grpc_mdctx *md_ctx;
   grpc_mdstr *authority_string;
   grpc_mdstr *path_string;
@@ -126,7 +126,7 @@
   channel_data *channeld = elem->channel_data;
 
   grpc_credentials *channel_creds =
-      channeld->security_context->request_metadata_creds;
+      channeld->security_connector->request_metadata_creds;
   /* TODO(jboeuf):
      Decide on the policy in this case:
      - populate both channel and call?
@@ -138,7 +138,7 @@
   if (channel_creds != NULL &&
       grpc_credentials_has_request_metadata(channel_creds)) {
     char *service_url =
-        build_service_url(channeld->security_context->base.url_scheme, calld);
+        build_service_url(channeld->security_connector->base.url_scheme, calld);
     calld->op = *op; /* Copy op (originates from the caller's stack). */
     grpc_credentials_get_request_metadata(channel_creds, service_url,
                                           on_credentials_metadata, elem);
@@ -193,8 +193,8 @@
         grpc_security_status status;
         const char *call_host = grpc_mdstr_as_c_string(calld->host);
         calld->op = *op; /* Copy op (originates from the caller's stack). */
-        status = grpc_channel_security_context_check_call_host(
-            channeld->security_context, call_host, on_host_checked, elem);
+        status = grpc_channel_security_connector_check_call_host(
+            channeld->security_connector, call_host, on_host_checked, elem);
         if (status != GRPC_SECURITY_OK) {
           if (status == GRPC_SECURITY_ERROR) {
             char *error_msg;
@@ -255,7 +255,7 @@
                               const grpc_channel_args *args,
                               grpc_mdctx *metadata_context, int is_first,
                               int is_last) {
-  grpc_security_context *ctx = grpc_find_security_context_in_args(args);
+  grpc_security_connector *ctx = grpc_find_security_connector_in_args(args);
   /* grab pointers to our data from the channel element */
   channel_data *channeld = elem->channel_data;
 
@@ -268,23 +268,24 @@
 
   /* initialize members */
   GPR_ASSERT(ctx->is_client_side);
-  channeld->security_context =
-      (grpc_channel_security_context *)grpc_security_context_ref(ctx);
+  channeld->security_connector =
+      (grpc_channel_security_connector *)grpc_security_connector_ref(ctx);
   channeld->md_ctx = metadata_context;
   channeld->authority_string =
       grpc_mdstr_from_string(channeld->md_ctx, ":authority");
   channeld->path_string = grpc_mdstr_from_string(channeld->md_ctx, ":path");
   channeld->error_msg_key =
       grpc_mdstr_from_string(channeld->md_ctx, "grpc-message");
-  channeld->status_key = grpc_mdstr_from_string(channeld->md_ctx, "grpc-status");
+  channeld->status_key =
+      grpc_mdstr_from_string(channeld->md_ctx, "grpc-status");
 }
 
 /* Destructor for channel data */
 static void destroy_channel_elem(grpc_channel_element *elem) {
   /* grab pointers to our data from the channel element */
   channel_data *channeld = elem->channel_data;
-  grpc_channel_security_context *ctx = channeld->security_context;
-  if (ctx != NULL) grpc_security_context_unref(&ctx->base);
+  grpc_channel_security_connector *ctx = channeld->security_connector;
+  if (ctx != NULL) grpc_security_connector_unref(&ctx->base);
   if (channeld->authority_string != NULL) {
     grpc_mdstr_unref(channeld->authority_string);
   }
@@ -300,6 +301,5 @@
 }
 
 const grpc_channel_filter grpc_client_auth_filter = {
-    call_op,           channel_op,           sizeof(call_data),
-    init_call_elem,    destroy_call_elem,    sizeof(channel_data),
-    init_channel_elem, destroy_channel_elem, "auth"};
+    call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
+    sizeof(channel_data), init_channel_elem, destroy_channel_elem, "auth"};
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index e6d2e9e..f6366f0 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -36,11 +36,14 @@
 #include <string.h>
 #include <stdio.h>
 
+#include "src/core/channel/channel_args.h"
+#include "src/core/channel/http_client_filter.h"
 #include "src/core/json/json.h"
 #include "src/core/httpcli/httpcli.h"
 #include "src/core/iomgr/iomgr.h"
 #include "src/core/security/json_token.h"
 #include "src/core/support/string.h"
+
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
@@ -111,9 +114,33 @@
   creds->vtable->get_request_metadata(creds, service_url, cb, user_data);
 }
 
-grpc_mdctx *grpc_credentials_get_metadata_context(grpc_credentials *creds) {
-  if (creds == NULL) return NULL;
-  return creds->vtable->get_metadata_context(creds);
+grpc_mdctx *grpc_credentials_get_or_create_metadata_context(
+    grpc_credentials *creds) {
+  grpc_mdctx *mdctx = NULL;
+  if (creds != NULL && creds->vtable->get_metadata_context != NULL) {
+    mdctx = creds->vtable->get_metadata_context(creds);
+  }
+  if (mdctx == NULL) {
+    return grpc_mdctx_create();
+  } else {
+    grpc_mdctx_ref(mdctx);
+    return mdctx;
+  }
+}
+
+grpc_security_status grpc_credentials_create_security_connector(
+    grpc_credentials *creds, const char *target, const grpc_channel_args *args,
+    grpc_credentials *request_metadata_creds,
+    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+  *new_args = NULL;
+  if (creds == NULL || creds->vtable->create_security_connector == NULL ||
+      grpc_credentials_has_request_metadata_only(creds)) {
+    gpr_log(GPR_ERROR,
+            "Invalid credentials for creating a security connector.");
+    return GRPC_SECURITY_ERROR;
+  }
+  return creds->vtable->create_security_connector(
+      creds, target, args, request_metadata_creds, sc, new_args);
 }
 
 void grpc_server_credentials_release(grpc_server_credentials *creds) {
@@ -121,6 +148,15 @@
   creds->vtable->destroy(creds);
 }
 
+grpc_security_status grpc_server_credentials_create_security_connector(
+    grpc_server_credentials *creds, grpc_security_connector **sc) {
+  if (creds == NULL || creds->vtable->create_security_connector == NULL) {
+    gpr_log(GPR_ERROR, "Server credentials cannot create security context.");
+    return GRPC_SECURITY_ERROR;
+  }
+  return creds->vtable->create_security_connector(creds, sc);
+}
+
 /* -- Ssl credentials. -- */
 
 typedef struct {
@@ -176,31 +212,48 @@
   return NULL;
 }
 
+static grpc_security_status ssl_create_security_connector(
+    grpc_credentials *creds, const char *target, const grpc_channel_args *args,
+    grpc_credentials *request_metadata_creds,
+    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+  grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
+  grpc_security_status status = GRPC_SECURITY_OK;
+  size_t i = 0;
+  const char *overridden_target_name = NULL;
+  grpc_arg arg;
+
+  for (i = 0; args && i < args->num_args; i++) {
+    grpc_arg *arg = &args->args[i];
+    if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 &&
+        arg->type == GRPC_ARG_STRING) {
+      overridden_target_name = arg->value.string;
+      break;
+    }
+  }
+  status = grpc_ssl_channel_security_connector_create(
+      request_metadata_creds, &c->config, target, overridden_target_name, sc);
+  if (status != GRPC_SECURITY_OK) {
+    return status;
+  }
+  arg.type = GRPC_ARG_STRING;
+  arg.key = GRPC_ARG_HTTP2_SCHEME;
+  arg.value.string = "https";
+  *new_args = grpc_channel_args_copy_and_add(args, &arg);
+  return status;
+}
+
+static grpc_security_status ssl_server_create_security_connector(
+    grpc_server_credentials *creds, grpc_security_connector **sc) {
+  grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
+  return grpc_ssl_server_security_connector_create(&c->config, sc);
+}
+
 static grpc_credentials_vtable ssl_vtable = {
     ssl_destroy, ssl_has_request_metadata, ssl_has_request_metadata_only,
-    ssl_get_metadata_context, NULL};
+    ssl_get_metadata_context, NULL, ssl_create_security_connector};
 
-static grpc_server_credentials_vtable ssl_server_vtable = {ssl_server_destroy};
-
-const grpc_ssl_config *grpc_ssl_credentials_get_config(
-    const grpc_credentials *creds) {
-  if (creds == NULL || strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
-    return NULL;
-  } else {
-    grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
-    return &c->config;
-  }
-}
-
-const grpc_ssl_server_config *grpc_ssl_server_credentials_get_config(
-    const grpc_server_credentials *creds) {
-  if (creds == NULL || strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) {
-    return NULL;
-  } else {
-    grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
-    return &c->config;
-  }
-}
+static grpc_server_credentials_vtable ssl_server_vtable = {
+    ssl_server_destroy, ssl_server_create_security_connector};
 
 static void ssl_copy_key_material(const char *input, unsigned char **output,
                                   size_t *output_size) {
@@ -388,7 +441,7 @@
 
 static grpc_credentials_vtable jwt_vtable = {
     jwt_destroy, jwt_has_request_metadata, jwt_has_request_metadata_only,
-    jwt_get_metadata_context, jwt_get_request_metadata};
+    jwt_get_metadata_context, jwt_get_request_metadata, NULL};
 
 grpc_credentials *grpc_jwt_credentials_create(const char *json_key,
                                               gpr_timespec token_lifetime) {
@@ -613,7 +666,7 @@
     oauth2_token_fetcher_destroy, oauth2_token_fetcher_has_request_metadata,
     oauth2_token_fetcher_has_request_metadata_only,
     oauth2_token_fetcher_get_metadata_context,
-    oauth2_token_fetcher_get_request_metadata};
+    oauth2_token_fetcher_get_request_metadata, NULL};
 
 static void compute_engine_fetch_oauth2(
     grpc_credentials_metadata_request *metadata_req,
@@ -657,7 +710,7 @@
     service_account_destroy, oauth2_token_fetcher_has_request_metadata,
     oauth2_token_fetcher_has_request_metadata_only,
     oauth2_token_fetcher_get_metadata_context,
-    oauth2_token_fetcher_get_request_metadata};
+    oauth2_token_fetcher_get_request_metadata, NULL};
 
 static void service_account_fetch_oauth2(
     grpc_credentials_metadata_request *metadata_req,
@@ -731,7 +784,7 @@
     refresh_token_destroy, oauth2_token_fetcher_has_request_metadata,
     oauth2_token_fetcher_has_request_metadata_only,
     oauth2_token_fetcher_get_metadata_context,
-    oauth2_token_fetcher_get_request_metadata};
+    oauth2_token_fetcher_get_request_metadata, NULL};
 
 static void refresh_token_fetch_oauth2(
     grpc_credentials_metadata_request *metadata_req,
@@ -834,7 +887,7 @@
 static grpc_credentials_vtable fake_oauth2_vtable = {
     fake_oauth2_destroy, fake_oauth2_has_request_metadata,
     fake_oauth2_has_request_metadata_only, fake_oauth2_get_metadata_context,
-    fake_oauth2_get_request_metadata};
+    fake_oauth2_get_request_metadata, NULL};
 
 grpc_credentials *grpc_fake_oauth2_credentials_create(
     const char *token_md_value, int is_async) {
@@ -878,15 +931,33 @@
   return NULL;
 }
 
+static grpc_security_status
+fake_transport_security_create_security_connector(
+    grpc_credentials *c, const char *target, const grpc_channel_args *args,
+    grpc_credentials *request_metadata_creds,
+    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+  *sc = grpc_fake_channel_security_connector_create(request_metadata_creds, 1);
+  return GRPC_SECURITY_OK;
+}
+
+static grpc_security_status
+fake_transport_security_server_create_security_connector(
+    grpc_server_credentials *c, grpc_security_connector **sc) {
+  *sc = grpc_fake_server_security_connector_create();
+  return GRPC_SECURITY_OK;
+}
+
 static grpc_credentials_vtable fake_transport_security_credentials_vtable = {
     fake_transport_security_credentials_destroy,
     fake_transport_security_has_request_metadata,
     fake_transport_security_has_request_metadata_only,
-    fake_transport_security_get_metadata_context, NULL};
+    fake_transport_security_get_metadata_context, NULL,
+    fake_transport_security_create_security_connector};
 
 static grpc_server_credentials_vtable
     fake_transport_security_server_credentials_vtable = {
-        fake_transport_security_server_credentials_destroy};
+        fake_transport_security_server_credentials_destroy,
+        fake_transport_security_server_create_security_connector};
 
 grpc_credentials *grpc_fake_transport_security_credentials_create(void) {
   grpc_credentials *c = gpr_malloc(sizeof(grpc_credentials));
@@ -911,6 +982,7 @@
 typedef struct {
   grpc_credentials base;
   grpc_credentials_array inner;
+  grpc_credentials *connector_creds;
 } grpc_composite_credentials;
 
 typedef struct {
@@ -1038,7 +1110,10 @@
   size_t i;
   for (i = 0; i < c->inner.num_creds; i++) {
     grpc_credentials *inner_creds = c->inner.creds_array[i];
-    grpc_mdctx *inner_ctx = grpc_credentials_get_metadata_context(inner_creds);
+    grpc_mdctx *inner_ctx = NULL;
+    if (inner_creds->vtable->get_metadata_context != NULL) {
+      inner_ctx = inner_creds->vtable->get_metadata_context(inner_creds);
+    }
     if (inner_ctx) {
       GPR_ASSERT(ctx == NULL &&
                  "can only have one metadata context per composite credential");
@@ -1048,10 +1123,24 @@
   return ctx;
 }
 
+static grpc_security_status composite_create_security_connector(
+    grpc_credentials *creds, const char *target, const grpc_channel_args *args,
+    grpc_credentials *request_metadata_creds,
+    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+  grpc_composite_credentials *c = (grpc_composite_credentials *)creds;
+  if (c->connector_creds == NULL) {
+    gpr_log(GPR_ERROR,
+            "Cannot create security connector, missing connector credentials.");
+    return GRPC_SECURITY_ERROR;
+  }
+  return grpc_credentials_create_security_connector(c->connector_creds, target,
+                                                    args, creds, sc, new_args);
+}
+
 static grpc_credentials_vtable composite_credentials_vtable = {
     composite_destroy, composite_has_request_metadata,
     composite_has_request_metadata_only, composite_get_metadata_context,
-    composite_get_request_metadata};
+    composite_get_request_metadata, composite_create_security_connector};
 
 static grpc_credentials_array get_creds_array(grpc_credentials **creds_addr) {
   grpc_credentials_array result;
@@ -1067,6 +1156,7 @@
 grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1,
                                                     grpc_credentials *creds2) {
   size_t i;
+  size_t creds_array_byte_size;
   grpc_credentials_array creds1_array;
   grpc_credentials_array creds2_array;
   grpc_composite_credentials *c;
@@ -1080,16 +1170,39 @@
   creds1_array = get_creds_array(&creds1);
   creds2_array = get_creds_array(&creds2);
   c->inner.num_creds = creds1_array.num_creds + creds2_array.num_creds;
-  c->inner.creds_array =
-      gpr_malloc(c->inner.num_creds * sizeof(grpc_credentials *));
+  creds_array_byte_size = c->inner.num_creds * sizeof(grpc_credentials *);
+  c->inner.creds_array = gpr_malloc(creds_array_byte_size);
+  memset(c->inner.creds_array, 0, creds_array_byte_size);
   for (i = 0; i < creds1_array.num_creds; i++) {
-    c->inner.creds_array[i] = grpc_credentials_ref(creds1_array.creds_array[i]);
+    grpc_credentials *cur_creds = creds1_array.creds_array[i];
+    if (!grpc_credentials_has_request_metadata_only(cur_creds)) {
+      if (c->connector_creds == NULL) {
+        c->connector_creds = cur_creds;
+      } else {
+        gpr_log(GPR_ERROR, "Cannot compose multiple connector credentials.");
+        goto fail;
+      }
+    }
+    c->inner.creds_array[i] = grpc_credentials_ref(cur_creds);
   }
   for (i = 0; i < creds2_array.num_creds; i++) {
+    grpc_credentials *cur_creds = creds2_array.creds_array[i];
+    if (!grpc_credentials_has_request_metadata_only(cur_creds)) {
+      if (c->connector_creds == NULL) {
+        c->connector_creds = cur_creds;
+      } else {
+        gpr_log(GPR_ERROR, "Cannot compose multiple connector credentials.");
+        goto fail;
+      }
+    }
     c->inner.creds_array[i + creds1_array.num_creds] =
-        grpc_credentials_ref(creds2_array.creds_array[i]);
+        grpc_credentials_ref(cur_creds);
   }
   return &c->base;
+
+fail:
+  grpc_credentials_unref(&c->base);
+  return NULL;
 }
 
 const grpc_credentials_array *grpc_composite_credentials_get_credentials(
@@ -1163,7 +1276,7 @@
 
 static grpc_credentials_vtable iam_vtable = {
     iam_destroy, iam_has_request_metadata, iam_has_request_metadata_only,
-    iam_get_metadata_context, iam_get_request_metadata};
+    iam_get_metadata_context, iam_get_request_metadata, NULL};
 
 grpc_credentials *grpc_iam_credentials_create(const char *token,
                                               const char *authority_selector) {
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index 562b3fa..87c773e 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -39,6 +39,8 @@
 #include <grpc/grpc_security.h>
 #include <grpc/support/sync.h>
 
+#include "src/core/security/security_connector.h"
+
 struct grpc_httpcli_response;
 
 /* --- Constants. --- */
@@ -99,6 +101,11 @@
                                const char *service_url,
                                grpc_credentials_metadata_cb cb,
                                void *user_data);
+  grpc_security_status (*create_security_connector)(
+      grpc_credentials *c, const char *target, const grpc_channel_args *args,
+      grpc_credentials *request_metadata_creds,
+      grpc_channel_security_connector **sc, grpc_channel_args **new_args);
+
 } grpc_credentials_vtable;
 
 struct grpc_credentials {
@@ -115,19 +122,20 @@
                                            const char *service_url,
                                            grpc_credentials_metadata_cb cb,
                                            void *user_data);
-grpc_mdctx *grpc_credentials_get_metadata_context(grpc_credentials *creds);
 
-typedef struct {
-  unsigned char *pem_private_key;
-  size_t pem_private_key_size;
-  unsigned char *pem_cert_chain;
-  size_t pem_cert_chain_size;
-  unsigned char *pem_root_certs;
-  size_t pem_root_certs_size;
-} grpc_ssl_config;
+/* Gets the mdctx from the credentials and increase the refcount if it exists,
+   otherwise, create a new one. */
+grpc_mdctx *grpc_credentials_get_or_create_metadata_context(
+    grpc_credentials *creds);
 
-const grpc_ssl_config *grpc_ssl_credentials_get_config(
-    const grpc_credentials *ssl_creds);
+/* Creates a security connector for the channel. May also create new channel
+   args for the channel to be used in place of the passed in const args if
+   returned non NULL. In that case the caller is responsible for destroying
+   new_args after channel creation. */
+grpc_security_status grpc_credentials_create_security_connector(
+    grpc_credentials *creds, const char *target, const grpc_channel_args *args,
+    grpc_credentials *request_metadata_creds,
+    grpc_channel_security_connector **sc, grpc_channel_args **new_args);
 
 typedef struct {
   grpc_credentials **creds_array;
@@ -159,6 +167,8 @@
 
 typedef struct {
   void (*destroy)(grpc_server_credentials *c);
+  grpc_security_status (*create_security_connector)(
+      grpc_server_credentials *c, grpc_security_connector **sc);
 } grpc_server_credentials_vtable;
 
 struct grpc_server_credentials {
@@ -166,17 +176,7 @@
   const char *type;
 };
 
-typedef struct {
-  unsigned char **pem_private_keys;
-  size_t *pem_private_keys_sizes;
-  unsigned char **pem_cert_chains;
-  size_t *pem_cert_chains_sizes;
-  size_t num_key_cert_pairs;
-  unsigned char *pem_root_certs;
-  size_t pem_root_certs_size;
-} grpc_ssl_server_config;
-
-const grpc_ssl_server_config *grpc_ssl_server_credentials_get_config(
-    const grpc_server_credentials *ssl_creds);
+grpc_security_status grpc_server_credentials_create_security_connector(
+    grpc_server_credentials *creds, grpc_security_connector **sc);
 
 #endif  /* GRPC_INTERNAL_CORE_SECURITY_CREDENTIALS_H */
diff --git a/src/core/security/factories.c b/src/core/security/factories.c
deleted file mode 100644
index 3d9216a..0000000
--- a/src/core/security/factories.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#include <string.h>
-
-#include <grpc/grpc.h>
-#include "src/core/security/credentials.h"
-#include "src/core/security/security_context.h"
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/useful.h>
-
-grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
-                                         const char *target,
-                                         const grpc_channel_args *args) {
-  grpc_secure_channel_factory factories[] = {
-      {GRPC_CREDENTIALS_TYPE_SSL, grpc_ssl_channel_create},
-      {GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY,
-       grpc_fake_transport_security_channel_create}};
-  return grpc_secure_channel_create_with_factories(
-      factories, GPR_ARRAY_SIZE(factories), creds, target, args);
-}
-
-grpc_security_status grpc_server_security_context_create(
-    grpc_server_credentials *creds, grpc_security_context **ctx) {
-  grpc_security_status status = GRPC_SECURITY_ERROR;
-
-  *ctx = NULL;
-  if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL) == 0) {
-    status = grpc_ssl_server_security_context_create(
-        grpc_ssl_server_credentials_get_config(creds), ctx);
-  } else if (strcmp(creds->type,
-                    GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) == 0) {
-    *ctx = grpc_fake_server_security_context_create();
-    status = GRPC_SECURITY_OK;
-  }
-  return status;
-}
diff --git a/src/core/security/secure_transport_setup.c b/src/core/security/secure_transport_setup.c
index f57d221..3e1db9a 100644
--- a/src/core/security/secure_transport_setup.c
+++ b/src/core/security/secure_transport_setup.c
@@ -43,7 +43,7 @@
 #define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
 
 typedef struct {
-  grpc_security_context *ctx;
+  grpc_security_connector *connector;
   tsi_handshaker *handshaker;
   unsigned char *handshake_buffer;
   size_t handshake_buffer_size;
@@ -74,7 +74,7 @@
   if (s->handshaker != NULL) tsi_handshaker_destroy(s->handshaker);
   if (s->handshake_buffer != NULL) gpr_free(s->handshake_buffer);
   gpr_slice_buffer_destroy(&s->left_overs);
-  grpc_security_context_unref(s->ctx);
+  grpc_security_connector_unref(s->connector);
   gpr_free(s);
 }
 
@@ -112,8 +112,8 @@
     secure_transport_setup_done(s, 0);
     return;
   }
-  peer_status =
-      grpc_security_context_check_peer(s->ctx, peer, on_peer_checked, s);
+  peer_status = grpc_security_connector_check_peer(s->connector, peer,
+                                                   on_peer_checked, s);
   if (peer_status == GRPC_SECURITY_ERROR) {
     gpr_log(GPR_ERROR, "Peer check failed.");
     secure_transport_setup_done(s, 0);
@@ -262,7 +262,7 @@
   }
 }
 
-void grpc_setup_secure_transport(grpc_security_context *ctx,
+void grpc_setup_secure_transport(grpc_security_connector *connector,
                                  grpc_endpoint *nonsecure_endpoint,
                                  grpc_secure_transport_setup_done_cb cb,
                                  void *user_data) {
@@ -270,12 +270,12 @@
   grpc_secure_transport_setup *s =
       gpr_malloc(sizeof(grpc_secure_transport_setup));
   memset(s, 0, sizeof(grpc_secure_transport_setup));
-  result = grpc_security_context_create_handshaker(ctx, &s->handshaker);
+  result = grpc_security_connector_create_handshaker(connector, &s->handshaker);
   if (result != GRPC_SECURITY_OK) {
     secure_transport_setup_done(s, 0);
     return;
   }
-  s->ctx = grpc_security_context_ref(ctx);
+  s->connector = grpc_security_connector_ref(connector);
   s->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
   s->handshake_buffer = gpr_malloc(s->handshake_buffer_size);
   s->endpoint = nonsecure_endpoint;
diff --git a/src/core/security/secure_transport_setup.h b/src/core/security/secure_transport_setup.h
index e1f8ed7..58701c4 100644
--- a/src/core/security/secure_transport_setup.h
+++ b/src/core/security/secure_transport_setup.h
@@ -35,7 +35,7 @@
 #define GRPC_INTERNAL_CORE_SECURITY_SECURE_TRANSPORT_SETUP_H
 
 #include "src/core/iomgr/endpoint.h"
-#include "src/core/security/security_context.h"
+#include "src/core/security/security_connector.h"
 
 /* --- Secure transport setup --- */
 
@@ -45,7 +45,7 @@
     grpc_endpoint *secure_endpoint);
 
 /* Calls the callback upon completion. */
-void grpc_setup_secure_transport(grpc_security_context *ctx,
+void grpc_setup_secure_transport(grpc_security_connector *connector,
                                  grpc_endpoint *nonsecure_endpoint,
                                  grpc_secure_transport_setup_done_cb cb,
                                  void *user_data);
diff --git a/src/core/security/security_context.c b/src/core/security/security_connector.c
similarity index 65%
rename from src/core/security/security_context.c
rename to src/core/security/security_connector.c
index dbfcf55..dbd79c5 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_connector.c
@@ -31,12 +31,10 @@
  *
  */
 
-#include "src/core/security/security_context.h"
+#include "src/core/security/security_connector.h"
 
 #include <string.h>
 
-#include "src/core/channel/channel_args.h"
-#include "src/core/channel/http_client_filter.h"
 #include "src/core/security/credentials.h"
 #include "src/core/security/secure_endpoint.h"
 #include "src/core/support/env.h"
@@ -56,7 +54,8 @@
 #ifndef INSTALL_PREFIX
 static const char *installed_roots_path = "/usr/share/grpc/roots.pem";
 #else
-static const char *installed_roots_path = INSTALL_PREFIX "/share/grpc/roots.pem";
+static const char *installed_roots_path =
+    INSTALL_PREFIX "/share/grpc/roots.pem";
 #endif
 
 /* -- Cipher suites. -- */
@@ -82,75 +81,77 @@
 
 /* -- Common methods. -- */
 
-grpc_security_status grpc_security_context_create_handshaker(
-    grpc_security_context *ctx, tsi_handshaker **handshaker) {
-  if (ctx == NULL || handshaker == NULL) return GRPC_SECURITY_ERROR;
-  return ctx->vtable->create_handshaker(ctx, handshaker);
+grpc_security_status grpc_security_connector_create_handshaker(
+    grpc_security_connector *sc, tsi_handshaker **handshaker) {
+  if (sc == NULL || handshaker == NULL) return GRPC_SECURITY_ERROR;
+  return sc->vtable->create_handshaker(sc, handshaker);
 }
 
-grpc_security_status grpc_security_context_check_peer(
-    grpc_security_context *ctx, tsi_peer peer, grpc_security_check_cb cb,
+grpc_security_status grpc_security_connector_check_peer(
+    grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb,
     void *user_data) {
-  if (ctx == NULL) {
+  if (sc == NULL) {
     tsi_peer_destruct(&peer);
     return GRPC_SECURITY_ERROR;
   }
-  return ctx->vtable->check_peer(ctx, peer, cb, user_data);
+  return sc->vtable->check_peer(sc, peer, cb, user_data);
 }
 
-grpc_security_status grpc_channel_security_context_check_call_host(
-    grpc_channel_security_context *ctx, const char *host,
+grpc_security_status grpc_channel_security_connector_check_call_host(
+    grpc_channel_security_connector *sc, const char *host,
     grpc_security_check_cb cb, void *user_data) {
-  if (ctx == NULL || ctx->check_call_host == NULL) return GRPC_SECURITY_ERROR;
-  return ctx->check_call_host(ctx, host, cb, user_data);
+  if (sc == NULL || sc->check_call_host == NULL) return GRPC_SECURITY_ERROR;
+  return sc->check_call_host(sc, host, cb, user_data);
 }
 
-void grpc_security_context_unref(grpc_security_context *ctx) {
-  if (ctx == NULL) return;
-  if (gpr_unref(&ctx->refcount)) ctx->vtable->destroy(ctx);
+void grpc_security_connector_unref(grpc_security_connector *sc) {
+  if (sc == NULL) return;
+  if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
 }
 
-grpc_security_context *grpc_security_context_ref(grpc_security_context *ctx) {
-  if (ctx == NULL) return NULL;
-  gpr_ref(&ctx->refcount);
-  return ctx;
+grpc_security_connector *grpc_security_connector_ref(
+    grpc_security_connector *sc) {
+  if (sc == NULL) return NULL;
+  gpr_ref(&sc->refcount);
+  return sc;
 }
 
-static void context_pointer_arg_destroy(void *p) {
-  grpc_security_context_unref(p);
+static void connector_pointer_arg_destroy(void *p) {
+  grpc_security_connector_unref(p);
 }
 
-static void *context_pointer_arg_copy(void *p) {
-  return grpc_security_context_ref(p);
+static void *connector_pointer_arg_copy(void *p) {
+  return grpc_security_connector_ref(p);
 }
 
-grpc_arg grpc_security_context_to_arg(grpc_security_context *ctx) {
+grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc) {
   grpc_arg result;
   result.type = GRPC_ARG_POINTER;
-  result.key = GRPC_SECURITY_CONTEXT_ARG;
-  result.value.pointer.destroy = context_pointer_arg_destroy;
-  result.value.pointer.copy = context_pointer_arg_copy;
-  result.value.pointer.p = ctx;
+  result.key = GRPC_SECURITY_CONNECTOR_ARG;
+  result.value.pointer.destroy = connector_pointer_arg_destroy;
+  result.value.pointer.copy = connector_pointer_arg_copy;
+  result.value.pointer.p = sc;
   return result;
 }
 
-grpc_security_context *grpc_security_context_from_arg(const grpc_arg *arg) {
-  if (strcmp(arg->key, GRPC_SECURITY_CONTEXT_ARG)) return NULL;
+grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg) {
+  if (strcmp(arg->key, GRPC_SECURITY_CONNECTOR_ARG)) return NULL;
   if (arg->type != GRPC_ARG_POINTER) {
     gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
-            GRPC_SECURITY_CONTEXT_ARG);
+            GRPC_SECURITY_CONNECTOR_ARG);
     return NULL;
   }
   return arg->value.pointer.p;
 }
 
-grpc_security_context *grpc_find_security_context_in_args(
+grpc_security_connector *grpc_find_security_connector_in_args(
     const grpc_channel_args *args) {
   size_t i;
   if (args == NULL) return NULL;
   for (i = 0; i < args->num_args; i++) {
-    grpc_security_context *ctx = grpc_security_context_from_arg(&args->args[i]);
-    if (ctx != NULL) return ctx;
+    grpc_security_connector *sc =
+        grpc_security_connector_from_arg(&args->args[i]);
+    if (sc != NULL) return sc;
   }
   return NULL;
 }
@@ -158,51 +159,41 @@
 static int check_request_metadata_creds(grpc_credentials *creds) {
   if (creds != NULL && !grpc_credentials_has_request_metadata(creds)) {
     gpr_log(GPR_ERROR,
-            "Incompatible credentials for channel security context: needs to "
+            "Incompatible credentials for channel security connector: needs to "
             "set request metadata.");
     return 0;
   }
   return 1;
 }
 
-static grpc_mdctx *get_or_create_mdctx(grpc_credentials *creds) {
-  grpc_mdctx *mdctx = grpc_credentials_get_metadata_context(creds);
-  if (mdctx == NULL) {
-    mdctx = grpc_mdctx_create();
-  } else {
-    grpc_mdctx_ref(mdctx);
-  }
-  return mdctx;
-}
-
 /* -- Fake implementation. -- */
 
 typedef struct {
-  grpc_channel_security_context base;
+  grpc_channel_security_connector base;
   int call_host_check_is_async;
-} grpc_fake_channel_security_context;
+} grpc_fake_channel_security_connector;
 
-static void fake_channel_destroy(grpc_security_context *ctx) {
-  grpc_channel_security_context *c = (grpc_channel_security_context *)ctx;
+static void fake_channel_destroy(grpc_security_connector *sc) {
+  grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
   grpc_credentials_unref(c->request_metadata_creds);
-  gpr_free(ctx);
+  gpr_free(sc);
 }
 
-static void fake_server_destroy(grpc_security_context *ctx) { gpr_free(ctx); }
+static void fake_server_destroy(grpc_security_connector *sc) { gpr_free(sc); }
 
 static grpc_security_status fake_channel_create_handshaker(
-    grpc_security_context *ctx, tsi_handshaker **handshaker) {
+    grpc_security_connector *sc, tsi_handshaker **handshaker) {
   *handshaker = tsi_create_fake_handshaker(1);
   return GRPC_SECURITY_OK;
 }
 
 static grpc_security_status fake_server_create_handshaker(
-    grpc_security_context *ctx, tsi_handshaker **handshaker) {
+    grpc_security_connector *sc, tsi_handshaker **handshaker) {
   *handshaker = tsi_create_fake_handshaker(0);
   return GRPC_SECURITY_OK;
 }
 
-static grpc_security_status fake_check_peer(grpc_security_context *ctx,
+static grpc_security_status fake_check_peer(grpc_security_connector *sc,
                                             tsi_peer peer,
                                             grpc_security_check_cb cb,
                                             void *user_data) {
@@ -238,10 +229,10 @@
 }
 
 static grpc_security_status fake_channel_check_call_host(
-    grpc_channel_security_context *ctx, const char *host,
+    grpc_channel_security_connector *sc, const char *host,
     grpc_security_check_cb cb, void *user_data) {
-  grpc_fake_channel_security_context *c =
-      (grpc_fake_channel_security_context *)ctx;
+  grpc_fake_channel_security_connector *c =
+      (grpc_fake_channel_security_connector *)sc;
   if (c->call_host_check_is_async) {
     cb(user_data, GRPC_SECURITY_OK);
     return GRPC_SECURITY_PENDING;
@@ -250,16 +241,16 @@
   }
 }
 
-static grpc_security_context_vtable fake_channel_vtable = {
+static grpc_security_connector_vtable fake_channel_vtable = {
     fake_channel_destroy, fake_channel_create_handshaker, fake_check_peer};
 
-static grpc_security_context_vtable fake_server_vtable = {
+static grpc_security_connector_vtable fake_server_vtable = {
     fake_server_destroy, fake_server_create_handshaker, fake_check_peer};
 
-grpc_channel_security_context *grpc_fake_channel_security_context_create(
+grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
     grpc_credentials *request_metadata_creds, int call_host_check_is_async) {
-  grpc_fake_channel_security_context *c =
-      gpr_malloc(sizeof(grpc_fake_channel_security_context));
+  grpc_fake_channel_security_connector *c =
+      gpr_malloc(sizeof(grpc_fake_channel_security_connector));
   gpr_ref_init(&c->base.base.refcount, 1);
   c->base.base.is_client_side = 1;
   c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
@@ -271,8 +262,8 @@
   return &c->base;
 }
 
-grpc_security_context *grpc_fake_server_security_context_create(void) {
-  grpc_security_context *c = gpr_malloc(sizeof(grpc_security_context));
+grpc_security_connector *grpc_fake_server_security_connector_create(void) {
+  grpc_security_connector *c = gpr_malloc(sizeof(grpc_security_connector));
   gpr_ref_init(&c->refcount, 1);
   c->vtable = &fake_server_vtable;
   c->url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
@@ -282,21 +273,21 @@
 /* --- Ssl implementation. --- */
 
 typedef struct {
-  grpc_channel_security_context base;
+  grpc_channel_security_connector base;
   tsi_ssl_handshaker_factory *handshaker_factory;
   char *target_name;
   char *overridden_target_name;
   tsi_peer peer;
-} grpc_ssl_channel_security_context;
+} grpc_ssl_channel_security_connector;
 
 typedef struct {
-  grpc_security_context base;
+  grpc_security_connector base;
   tsi_ssl_handshaker_factory *handshaker_factory;
-} grpc_ssl_server_security_context;
+} grpc_ssl_server_security_connector;
 
-static void ssl_channel_destroy(grpc_security_context *ctx) {
-  grpc_ssl_channel_security_context *c =
-      (grpc_ssl_channel_security_context *)ctx;
+static void ssl_channel_destroy(grpc_security_connector *sc) {
+  grpc_ssl_channel_security_connector *c =
+      (grpc_ssl_channel_security_connector *)sc;
   grpc_credentials_unref(c->base.request_metadata_creds);
   if (c->handshaker_factory != NULL) {
     tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
@@ -304,15 +295,16 @@
   if (c->target_name != NULL) gpr_free(c->target_name);
   if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
   tsi_peer_destruct(&c->peer);
-  gpr_free(ctx);
+  gpr_free(sc);
 }
 
-static void ssl_server_destroy(grpc_security_context *ctx) {
-  grpc_ssl_server_security_context *c = (grpc_ssl_server_security_context *)ctx;
+static void ssl_server_destroy(grpc_security_connector *sc) {
+  grpc_ssl_server_security_connector *c =
+      (grpc_ssl_server_security_connector *)sc;
   if (c->handshaker_factory != NULL) {
     tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
   }
-  gpr_free(ctx);
+  gpr_free(sc);
 }
 
 static grpc_security_status ssl_create_handshaker(
@@ -331,9 +323,9 @@
 }
 
 static grpc_security_status ssl_channel_create_handshaker(
-    grpc_security_context *ctx, tsi_handshaker **handshaker) {
-  grpc_ssl_channel_security_context *c =
-      (grpc_ssl_channel_security_context *)ctx;
+    grpc_security_connector *sc, tsi_handshaker **handshaker) {
+  grpc_ssl_channel_security_connector *c =
+      (grpc_ssl_channel_security_connector *)sc;
   return ssl_create_handshaker(c->handshaker_factory, 1,
                                c->overridden_target_name != NULL
                                    ? c->overridden_target_name
@@ -342,13 +334,13 @@
 }
 
 static grpc_security_status ssl_server_create_handshaker(
-    grpc_security_context *ctx, tsi_handshaker **handshaker) {
-  grpc_ssl_server_security_context *c = (grpc_ssl_server_security_context *)ctx;
+    grpc_security_connector *sc, tsi_handshaker **handshaker) {
+  grpc_ssl_server_security_connector *c =
+      (grpc_ssl_server_security_connector *)sc;
   return ssl_create_handshaker(c->handshaker_factory, 0, NULL, handshaker);
 }
 
-static int ssl_host_matches_name(const tsi_peer *peer,
-                                 const char *peer_name) {
+static int ssl_host_matches_name(const tsi_peer *peer, const char *peer_name) {
   char *allocated_name = NULL;
   int r;
 
@@ -384,8 +376,7 @@
   }
 
   /* Check the peer name if specified. */
-  if (peer_name != NULL &&
-      !ssl_host_matches_name(peer, peer_name)) {
+  if (peer_name != NULL && !ssl_host_matches_name(peer, peer_name)) {
     gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name);
     return GRPC_SECURITY_ERROR;
   }
@@ -393,12 +384,12 @@
   return GRPC_SECURITY_OK;
 }
 
-static grpc_security_status ssl_channel_check_peer(grpc_security_context *ctx,
+static grpc_security_status ssl_channel_check_peer(grpc_security_connector *sc,
                                                    tsi_peer peer,
                                                    grpc_security_check_cb cb,
                                                    void *user_data) {
-  grpc_ssl_channel_security_context *c =
-      (grpc_ssl_channel_security_context *)ctx;
+  grpc_ssl_channel_security_connector *c =
+      (grpc_ssl_channel_security_connector *)sc;
   grpc_security_status status;
   tsi_peer_destruct(&c->peer);
   c->peer = peer;
@@ -409,7 +400,7 @@
   return status;
 }
 
-static grpc_security_status ssl_server_check_peer(grpc_security_context *ctx,
+static grpc_security_status ssl_server_check_peer(grpc_security_connector *sc,
                                                   tsi_peer peer,
                                                   grpc_security_check_cb cb,
                                                   void *user_data) {
@@ -420,10 +411,10 @@
 }
 
 static grpc_security_status ssl_channel_check_call_host(
-    grpc_channel_security_context *ctx, const char *host,
+    grpc_channel_security_connector *sc, const char *host,
     grpc_security_check_cb cb, void *user_data) {
-  grpc_ssl_channel_security_context *c =
-      (grpc_ssl_channel_security_context *)ctx;
+  grpc_ssl_channel_security_connector *c =
+      (grpc_ssl_channel_security_connector *)sc;
 
   if (ssl_host_matches_name(&c->peer, host)) return GRPC_SECURITY_OK;
 
@@ -437,10 +428,10 @@
   }
 }
 
-static grpc_security_context_vtable ssl_channel_vtable = {
+static grpc_security_connector_vtable ssl_channel_vtable = {
     ssl_channel_destroy, ssl_channel_create_handshaker, ssl_channel_check_peer};
 
-static grpc_security_context_vtable ssl_server_vtable = {
+static grpc_security_connector_vtable ssl_server_vtable = {
     ssl_server_destroy, ssl_server_create_handshaker, ssl_server_check_peer};
 
 static gpr_slice default_pem_root_certs;
@@ -471,17 +462,17 @@
   return GPR_SLICE_LENGTH(default_pem_root_certs);
 }
 
-grpc_security_status grpc_ssl_channel_security_context_create(
+grpc_security_status grpc_ssl_channel_security_connector_create(
     grpc_credentials *request_metadata_creds, const grpc_ssl_config *config,
     const char *target_name, const char *overridden_target_name,
-    grpc_channel_security_context **ctx) {
+    grpc_channel_security_connector **sc) {
   size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
   const unsigned char **alpn_protocol_strings =
       gpr_malloc(sizeof(const char *) * num_alpn_protocols);
   unsigned char *alpn_protocol_string_lengths =
       gpr_malloc(sizeof(unsigned char) * num_alpn_protocols);
   tsi_result result = TSI_OK;
-  grpc_ssl_channel_security_context *c;
+  grpc_ssl_channel_security_connector *c;
   size_t i;
   const unsigned char *pem_root_certs;
   size_t pem_root_certs_size;
@@ -502,8 +493,8 @@
     goto error;
   }
 
-  c = gpr_malloc(sizeof(grpc_ssl_channel_security_context));
-  memset(c, 0, sizeof(grpc_ssl_channel_security_context));
+  c = gpr_malloc(sizeof(grpc_ssl_channel_security_connector));
+  memset(c, 0, sizeof(grpc_ssl_channel_security_connector));
 
   gpr_ref_init(&c->base.base.refcount, 1);
   c->base.base.vtable = &ssl_channel_vtable;
@@ -535,10 +526,10 @@
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
     ssl_channel_destroy(&c->base.base);
-    *ctx = NULL;
+    *sc = NULL;
     goto error;
   }
-  *ctx = &c->base;
+  *sc = &c->base;
   gpr_free(alpn_protocol_strings);
   gpr_free(alpn_protocol_string_lengths);
   return GRPC_SECURITY_OK;
@@ -549,15 +540,15 @@
   return GRPC_SECURITY_ERROR;
 }
 
-grpc_security_status grpc_ssl_server_security_context_create(
-    const grpc_ssl_server_config *config, grpc_security_context **ctx) {
+grpc_security_status grpc_ssl_server_security_connector_create(
+    const grpc_ssl_server_config *config, grpc_security_connector **sc) {
   size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
   const unsigned char **alpn_protocol_strings =
       gpr_malloc(sizeof(const char *) * num_alpn_protocols);
   unsigned char *alpn_protocol_string_lengths =
       gpr_malloc(sizeof(unsigned char) * num_alpn_protocols);
   tsi_result result = TSI_OK;
-  grpc_ssl_server_security_context *c;
+  grpc_ssl_server_security_connector *c;
   size_t i;
 
   for (i = 0; i < num_alpn_protocols; i++) {
@@ -571,8 +562,8 @@
     gpr_log(GPR_ERROR, "An SSL server needs a key and a cert.");
     goto error;
   }
-  c = gpr_malloc(sizeof(grpc_ssl_server_security_context));
-  memset(c, 0, sizeof(grpc_ssl_server_security_context));
+  c = gpr_malloc(sizeof(grpc_ssl_server_security_connector));
+  memset(c, 0, sizeof(grpc_ssl_server_security_connector));
 
   gpr_ref_init(&c->base.refcount, 1);
   c->base.url_scheme = GRPC_SSL_URL_SCHEME;
@@ -582,17 +573,17 @@
       config->pem_private_keys_sizes,
       (const unsigned char **)config->pem_cert_chains,
       config->pem_cert_chains_sizes, config->num_key_cert_pairs,
-      config->pem_root_certs, config->pem_root_certs_size,
-      ssl_cipher_suites(), alpn_protocol_strings,
-      alpn_protocol_string_lengths, num_alpn_protocols, &c->handshaker_factory);
+      config->pem_root_certs, config->pem_root_certs_size, ssl_cipher_suites(),
+      alpn_protocol_strings, alpn_protocol_string_lengths, num_alpn_protocols,
+      &c->handshaker_factory);
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
     ssl_server_destroy(&c->base);
-    *ctx = NULL;
+    *sc = NULL;
     goto error;
   }
-  *ctx = &c->base;
+  *sc = &c->base;
   gpr_free(alpn_protocol_strings);
   gpr_free(alpn_protocol_string_lengths);
   return GRPC_SECURITY_OK;
@@ -603,84 +594,3 @@
   return GRPC_SECURITY_ERROR;
 }
 
-/* -- High level objects. -- */
-
-grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
-                                      grpc_credentials *request_metadata_creds,
-                                      const char *target,
-                                      const grpc_channel_args *args) {
-  grpc_channel_security_context *ctx = NULL;
-  grpc_channel *channel = NULL;
-  grpc_security_status status = GRPC_SECURITY_OK;
-  size_t i = 0;
-  const char *overridden_target_name = NULL;
-  grpc_arg arg;
-  grpc_channel_args *new_args;
-
-  for (i = 0; args && i < args->num_args; i++) {
-    grpc_arg *arg = &args->args[i];
-    if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 &&
-        arg->type == GRPC_ARG_STRING) {
-      overridden_target_name = arg->value.string;
-      break;
-    }
-  }
-  status = grpc_ssl_channel_security_context_create(
-      request_metadata_creds, grpc_ssl_credentials_get_config(ssl_creds),
-      target, overridden_target_name, &ctx);
-  if (status != GRPC_SECURITY_OK) {
-    return grpc_lame_client_channel_create();
-  }
-  arg.type = GRPC_ARG_STRING;
-  arg.key = GRPC_ARG_HTTP2_SCHEME;
-  arg.value.string = "https";
-  new_args = grpc_channel_args_copy_and_add(args, &arg);
-  channel = grpc_secure_channel_create_internal(
-      target, new_args, ctx, get_or_create_mdctx(request_metadata_creds));
-  grpc_security_context_unref(&ctx->base);
-  grpc_channel_args_destroy(new_args);
-  return channel;
-}
-
-grpc_channel *grpc_fake_transport_security_channel_create(
-    grpc_credentials *fake_creds, grpc_credentials *request_metadata_creds,
-    const char *target, const grpc_channel_args *args) {
-  grpc_channel_security_context *ctx =
-      grpc_fake_channel_security_context_create(request_metadata_creds, 1);
-  grpc_channel *channel = grpc_secure_channel_create_internal(
-      target, args, ctx, get_or_create_mdctx(request_metadata_creds));
-  grpc_security_context_unref(&ctx->base);
-  return channel;
-}
-
-grpc_channel *grpc_secure_channel_create_with_factories(
-    const grpc_secure_channel_factory *factories, size_t num_factories,
-    grpc_credentials *creds, const char *target,
-    const grpc_channel_args *args) {
-  size_t i;
-  if (creds == NULL) {
-    gpr_log(GPR_ERROR, "No credentials to create a secure channel.");
-    return grpc_lame_client_channel_create();
-  }
-  if (grpc_credentials_has_request_metadata_only(creds)) {
-    gpr_log(GPR_ERROR,
-            "Credentials is insufficient to create a secure channel.");
-    return grpc_lame_client_channel_create();
-  }
-
-  for (i = 0; i < num_factories; i++) {
-    grpc_credentials *composite_creds = NULL;
-    grpc_credentials *transport_security_creds = NULL;
-    transport_security_creds = grpc_credentials_contains_type(
-        creds, factories[i].creds_type, &composite_creds);
-    if (transport_security_creds != NULL) {
-      return factories[i].factory(transport_security_creds, composite_creds,
-                                  target, args);
-    }
-  }
-
-  gpr_log(GPR_ERROR,
-          "Unknown credentials type %s for creating a secure channel.",
-          creds->type);
-  return grpc_lame_client_channel_create();
-}
diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h
new file mode 100644
index 0000000..47abe05
--- /dev/null
+++ b/src/core/security/security_connector.h
@@ -0,0 +1,201 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONNECTOR_H
+#define GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONNECTOR_H
+
+#include <grpc/grpc_security.h>
+#include "src/core/iomgr/endpoint.h"
+#include "src/core/tsi/transport_security_interface.h"
+
+/* --- status enum. --- */
+
+typedef enum {
+  GRPC_SECURITY_OK = 0,
+  GRPC_SECURITY_PENDING,
+  GRPC_SECURITY_ERROR
+} grpc_security_status;
+
+/* --- URL schemes. --- */
+
+#define GRPC_SSL_URL_SCHEME "https"
+#define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security"
+
+/* --- security_connector object. ---
+
+    A security connector object represents away to configure the underlying
+    transport security mechanism and check the resulting trusted peer.  */
+
+typedef struct grpc_security_connector grpc_security_connector;
+
+#define GRPC_SECURITY_CONNECTOR_ARG "grpc.security_connector"
+
+typedef void (*grpc_security_check_cb)(void *user_data,
+                                       grpc_security_status status);
+
+typedef struct {
+  void (*destroy)(grpc_security_connector *sc);
+  grpc_security_status (*create_handshaker)(grpc_security_connector *sc,
+                                            tsi_handshaker **handshaker);
+  grpc_security_status (*check_peer)(grpc_security_connector *sc, tsi_peer peer,
+                                     grpc_security_check_cb cb,
+                                     void *user_data);
+} grpc_security_connector_vtable;
+
+struct grpc_security_connector {
+  const grpc_security_connector_vtable *vtable;
+  gpr_refcount refcount;
+  int is_client_side;
+  const char *url_scheme;
+};
+
+/* Increments the refcount. */
+grpc_security_connector *grpc_security_connector_ref(
+    grpc_security_connector *sc);
+
+/* Decrements the refcount and destroys the object if it reaches 0. */
+void grpc_security_connector_unref(grpc_security_connector *sc);
+
+/* Handshake creation. */
+grpc_security_status grpc_security_connector_create_handshaker(
+    grpc_security_connector *sc, tsi_handshaker **handshaker);
+
+/* Check the peer.
+   Implementations can choose to check the peer either synchronously or
+   asynchronously. In the first case, a successful call will return
+   GRPC_SECURITY_OK. In the asynchronous case, the call will return
+   GRPC_SECURITY_PENDING unless an error is detected early on.
+   Ownership of the peer is transfered.
+*/
+grpc_security_status grpc_security_connector_check_peer(
+    grpc_security_connector *sc, tsi_peer peer, grpc_security_check_cb cb,
+    void *user_data);
+
+/* Util to encapsulate the connector in a channel arg. */
+grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc);
+
+/* Util to get the connector from a channel arg. */
+grpc_security_connector *grpc_security_connector_from_arg(const grpc_arg *arg);
+
+/* Util to find the connector from channel args. */
+grpc_security_connector *grpc_find_security_connector_in_args(
+    const grpc_channel_args *args);
+
+/* --- channel_security_connector object. ---
+
+    A channel security connector object represents away to configure the
+    underlying transport security mechanism on the client side.  */
+
+typedef struct grpc_channel_security_connector grpc_channel_security_connector;
+
+struct grpc_channel_security_connector {
+  grpc_security_connector base; /* requires is_client_side to be non 0. */
+  grpc_credentials *request_metadata_creds;
+  grpc_security_status (*check_call_host)(grpc_channel_security_connector *sc,
+                                          const char *host,
+                                          grpc_security_check_cb cb,
+                                          void *user_data);
+};
+
+/* Checks that the host that will be set for a call is acceptable.
+   Implementations can choose do the check either synchronously or
+   asynchronously. In the first case, a successful call will return
+   GRPC_SECURITY_OK. In the asynchronous case, the call will return
+   GRPC_SECURITY_PENDING unless an error is detected early on. */
+grpc_security_status grpc_channel_security_connector_check_call_host(
+    grpc_channel_security_connector *sc, const char *host,
+    grpc_security_check_cb cb, void *user_data);
+
+/* --- Creation security connectors. --- */
+
+/* For TESTING ONLY!
+   Creates a fake connector that emulates real channel security.  */
+grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
+    grpc_credentials *request_metadata_creds, int call_host_check_is_async);
+
+/* For TESTING ONLY!
+   Creates a fake connector that emulates real server security.  */
+grpc_security_connector *grpc_fake_server_security_connector_create(void);
+
+/* Config for ssl clients. */
+typedef struct {
+  unsigned char *pem_private_key;
+  size_t pem_private_key_size;
+  unsigned char *pem_cert_chain;
+  size_t pem_cert_chain_size;
+  unsigned char *pem_root_certs;
+  size_t pem_root_certs_size;
+} grpc_ssl_config;
+
+/* Creates an SSL channel_security_connector.
+   - request_metadata_creds is the credentials object which metadata
+     will be sent with each request. This parameter can be NULL.
+   - config is the SSL config to be used for the SSL channel establishment.
+   - is_client should be 0 for a server or a non-0 value for a client.
+   - secure_peer_name is the secure peer name that should be checked in
+     grpc_channel_security_connector_check_peer. This parameter may be NULL in
+     which case the peer name will not be checked. Note that if this parameter
+     is not NULL, then, pem_root_certs should not be NULL either.
+   - sc is a pointer on the connector to be created.
+  This function returns GRPC_SECURITY_OK in case of success or a
+  specific error code otherwise.
+*/
+grpc_security_status grpc_ssl_channel_security_connector_create(
+    grpc_credentials *request_metadata_creds,
+    const grpc_ssl_config *config, const char *target_name,
+    const char *overridden_target_name, grpc_channel_security_connector **sc);
+
+/* Gets the default ssl roots. */
+size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs);
+
+/* Config for ssl servers. */
+typedef struct {
+  unsigned char **pem_private_keys;
+  size_t *pem_private_keys_sizes;
+  unsigned char **pem_cert_chains;
+  size_t *pem_cert_chains_sizes;
+  size_t num_key_cert_pairs;
+  unsigned char *pem_root_certs;
+  size_t pem_root_certs_size;
+} grpc_ssl_server_config;
+
+/* Creates an SSL server_security_connector.
+   - config is the SSL config to be used for the SSL channel establishment.
+   - sc is a pointer on the connector to be created.
+  This function returns GRPC_SECURITY_OK in case of success or a
+  specific error code otherwise.
+*/
+grpc_security_status grpc_ssl_server_security_connector_create(
+    const grpc_ssl_server_config *config, grpc_security_connector **sc);
+
+#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONNECTOR_H */
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
deleted file mode 100644
index 8e7ba34..0000000
--- a/src/core/security/security_context.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H
-#define GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H
-
-#include <grpc/grpc_security.h>
-#include "src/core/iomgr/endpoint.h"
-#include "src/core/security/credentials.h"
-#include "src/core/tsi/transport_security_interface.h"
-
-/* --- status enum. --- */
-
-typedef enum {
-  GRPC_SECURITY_OK = 0,
-  GRPC_SECURITY_PENDING,
-  GRPC_SECURITY_ERROR
-} grpc_security_status;
-
-/* --- URL schemes. --- */
-
-#define GRPC_SSL_URL_SCHEME "https"
-#define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security"
-
-/* --- security_context object. ---
-
-    A security context object represents away to configure the underlying
-    transport security mechanism and check the resulting trusted peer.  */
-
-typedef struct grpc_security_context grpc_security_context;
-
-#define GRPC_SECURITY_CONTEXT_ARG "grpc.security_context"
-
-typedef void (*grpc_security_check_cb)(void *user_data,
-                                       grpc_security_status status);
-
-typedef struct {
-  void (*destroy)(grpc_security_context *ctx);
-  grpc_security_status (*create_handshaker)(grpc_security_context *ctx,
-                                            tsi_handshaker **handshaker);
-  grpc_security_status (*check_peer)(grpc_security_context *ctx, tsi_peer peer,
-                                     grpc_security_check_cb cb,
-                                     void *user_data);
-} grpc_security_context_vtable;
-
-struct grpc_security_context {
-  const grpc_security_context_vtable *vtable;
-  gpr_refcount refcount;
-  int is_client_side;
-  const char *url_scheme;
-};
-
-/* Increments the refcount. */
-grpc_security_context *grpc_security_context_ref(grpc_security_context *ctx);
-
-/* Decrements the refcount and destroys the object if it reaches 0. */
-void grpc_security_context_unref(grpc_security_context *ctx);
-
-/* Handshake creation. */
-grpc_security_status grpc_security_context_create_handshaker(
-    grpc_security_context *ctx, tsi_handshaker **handshaker);
-
-/* Check the peer.
-   Implementations can choose to check the peer either synchronously or
-   asynchronously. In the first case, a successful call will return
-   GRPC_SECURITY_OK. In the asynchronous case, the call will return
-   GRPC_SECURITY_PENDING unless an error is detected early on.
-   Ownership of the peer is transfered.
-*/
-grpc_security_status grpc_security_context_check_peer(
-    grpc_security_context *ctx, tsi_peer peer,
-    grpc_security_check_cb cb, void *user_data);
-
-/* Util to encapsulate the context in a channel arg. */
-grpc_arg grpc_security_context_to_arg(grpc_security_context *ctx);
-
-/* Util to get the context from a channel arg. */
-grpc_security_context *grpc_security_context_from_arg(const grpc_arg *arg);
-
-/* Util to find the context from channel args. */
-grpc_security_context *grpc_find_security_context_in_args(
-    const grpc_channel_args *args);
-
-/* --- channel_security_context object. ---
-
-    A channel security context object represents away to configure the
-    underlying transport security mechanism on the client side.  */
-
-typedef struct grpc_channel_security_context grpc_channel_security_context;
-
-struct grpc_channel_security_context {
-  grpc_security_context base; /* requires is_client_side to be non 0. */
-  grpc_credentials *request_metadata_creds;
-  grpc_security_status (*check_call_host)(
-      grpc_channel_security_context *ctx, const char *host,
-      grpc_security_check_cb cb, void *user_data);
-};
-
-/* Checks that the host that will be set for a call is acceptable.
-   Implementations can choose do the check either synchronously or
-   asynchronously. In the first case, a successful call will return
-   GRPC_SECURITY_OK. In the asynchronous case, the call will return
-   GRPC_SECURITY_PENDING unless an error is detected early on. */
-grpc_security_status grpc_channel_security_context_check_call_host(
-    grpc_channel_security_context *ctx, const char *host,
-    grpc_security_check_cb cb, void *user_data);
-
-/* --- Creation security contexts. --- */
-
-/* For TESTING ONLY!
-   Creates a fake context that emulates real channel security.  */
-grpc_channel_security_context *grpc_fake_channel_security_context_create(
-    grpc_credentials *request_metadata_creds, int call_host_check_is_async);
-
-/* For TESTING ONLY!
-   Creates a fake context that emulates real server security.  */
-grpc_security_context *grpc_fake_server_security_context_create(void);
-
-/* Creates an SSL channel_security_context.
-   - request_metadata_creds is the credentials object which metadata
-     will be sent with each request. This parameter can be NULL.
-   - config is the SSL config to be used for the SSL channel establishment.
-   - is_client should be 0 for a server or a non-0 value for a client.
-   - secure_peer_name is the secure peer name that should be checked in
-     grpc_channel_security_context_check_peer. This parameter may be NULL in
-     which case the peer name will not be checked. Note that if this parameter
-     is not NULL, then, pem_root_certs should not be NULL either.
-   - ctx is a pointer on the context to be created.
-  This function returns GRPC_SECURITY_OK in case of success or a
-  specific error code otherwise.
-*/
-grpc_security_status grpc_ssl_channel_security_context_create(
-    grpc_credentials *request_metadata_creds, const grpc_ssl_config *config,
-    const char *target_name, const char *overridden_target_name,
-    grpc_channel_security_context **ctx);
-
-/* Creates an SSL server_security_context.
-   - config is the SSL config to be used for the SSL channel establishment.
-   - ctx is a pointer on the context to be created.
-  This function returns GRPC_SECURITY_OK in case of success or a
-  specific error code otherwise.
-*/
-grpc_security_status grpc_ssl_server_security_context_create(
-    const grpc_ssl_server_config *config, grpc_security_context **ctx);
-
-/* --- Creation of high level objects. --- */
-
-/* Secure client channel creation. */
-
-size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs);
-
-grpc_channel *grpc_ssl_channel_create(grpc_credentials *ssl_creds,
-                                      grpc_credentials *request_metadata_creds,
-                                      const char *target,
-                                      const grpc_channel_args *args);
-
-grpc_channel *grpc_fake_transport_security_channel_create(
-    grpc_credentials *fake_creds, grpc_credentials *request_metadata_creds,
-    const char *target, const grpc_channel_args *args);
-
-grpc_channel *grpc_secure_channel_create_internal(
-    const char *target, const grpc_channel_args *args,
-    grpc_channel_security_context *ctx, grpc_mdctx *mdctx);
-
-typedef grpc_channel *(*grpc_secure_channel_factory_func)(
-    grpc_credentials *transport_security_creds,
-    grpc_credentials *request_metadata_creds, const char *target,
-    const grpc_channel_args *args);
-
-typedef struct {
-  const char *creds_type;
-  grpc_secure_channel_factory_func factory;
-} grpc_secure_channel_factory;
-
-grpc_channel *grpc_secure_channel_create_with_factories(
-    const grpc_secure_channel_factory *factories, size_t num_factories,
-    grpc_credentials *creds, const char *target, const grpc_channel_args *args);
-
-/* Secure server context creation. */
-
-grpc_security_status grpc_server_security_context_create(
-    grpc_server_credentials *creds, grpc_security_context **ctx);
-
-#endif  /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H */
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index 165ed54..5b7d99c 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -40,7 +40,8 @@
 #include "src/core/iomgr/endpoint.h"
 #include "src/core/iomgr/resolve_address.h"
 #include "src/core/iomgr/tcp_server.h"
-#include "src/core/security/security_context.h"
+#include "src/core/security/credentials.h"
+#include "src/core/security/security_connector.h"
 #include "src/core/security/secure_transport_setup.h"
 #include "src/core/surface/server.h"
 #include "src/core/transport/chttp2_transport.h"
@@ -52,7 +53,7 @@
 typedef struct grpc_server_secure_state {
   grpc_server *server;
   grpc_tcp_server *tcp;
-  grpc_security_context *ctx;
+  grpc_security_connector *sc;
   int is_shutdown;
   gpr_mu mu;
   gpr_refcount refcount;
@@ -64,7 +65,7 @@
 
 static void state_unref(grpc_server_secure_state *state) {
   if (gpr_unref(&state->refcount)) {
-    grpc_security_context_unref(state->ctx);
+    grpc_security_connector_unref(state->sc);
     gpr_free(state);
   }
 }
@@ -104,7 +105,7 @@
 static void on_accept(void *statep, grpc_endpoint *tcp) {
   grpc_server_secure_state *state = statep;
   state_ref(state);
-  grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done,
+  grpc_setup_secure_transport(state->sc, tcp, on_secure_transport_setup_done,
                               state);
 }
 
@@ -137,11 +138,11 @@
   int port_num = -1;
   int port_temp;
   grpc_security_status status = GRPC_SECURITY_ERROR;
-  grpc_security_context *ctx = NULL;
+  grpc_security_connector *sc = NULL;
 
   /* create security context */
   if (creds == NULL) goto error;
-  status = grpc_server_security_context_create(creds, &ctx);
+  status = grpc_server_credentials_create_security_connector(creds, &sc);
   if (status != GRPC_SECURITY_OK) {
     gpr_log(GPR_ERROR,
             "Unable to create secure server with credentials of type %s.",
@@ -188,7 +189,7 @@
   state = gpr_malloc(sizeof(*state));
   state->server = server;
   state->tcp = tcp;
-  state->ctx = ctx;
+  state->sc = sc;
   state->is_shutdown = 0;
   gpr_mu_init(&state->mu);
   gpr_ref_init(&state->refcount, 1);
@@ -200,8 +201,8 @@
 
 /* Error path: cleanup and return */
 error:
-  if (ctx) {
-    grpc_security_context_unref(ctx);
+  if (sc) {
+    grpc_security_connector_unref(sc);
   }
   if (resolved) {
     grpc_resolved_addresses_destroy(resolved);
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index 96b2fe0..e7d223b 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -48,7 +48,7 @@
 #include "src/core/iomgr/resolve_address.h"
 #include "src/core/iomgr/tcp_client.h"
 #include "src/core/security/auth.h"
-#include "src/core/security/security_context.h"
+#include "src/core/security/credentials.h"
 #include "src/core/security/secure_transport_setup.h"
 #include "src/core/support/string.h"
 #include "src/core/surface/channel.h"
@@ -74,7 +74,7 @@
 } request;
 
 struct setup {
-  grpc_channel_security_context *security_context;
+  grpc_channel_security_connector *security_connector;
   const char *target;
   grpc_transport_setup_callback setup_callback;
   void *setup_user_data;
@@ -130,7 +130,7 @@
       return;
     }
   } else {
-    grpc_setup_secure_transport(&r->setup->security_context->base, tcp,
+    grpc_setup_secure_transport(&r->setup->security_connector->base, tcp,
                                 on_secure_transport_setup_done, r);
   }
 }
@@ -185,7 +185,7 @@
 static void done_setup(void *sp) {
   setup *s = sp;
   gpr_free((void *)s->target);
-  grpc_security_context_unref(&s->security_context->base);
+  grpc_security_connector_unref(&s->security_connector->base);
   gpr_free(s);
 }
 
@@ -203,23 +203,37 @@
    Asynchronously: - resolve target
                    - connect to it (trying alternatives as presented)
                    - perform handshakes */
-grpc_channel *grpc_secure_channel_create_internal(
-    const char *target, const grpc_channel_args *args,
-    grpc_channel_security_context *context, grpc_mdctx *mdctx) {
+grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
+                                         const char *target,
+                                         const grpc_channel_args *args) {
   setup *s;
   grpc_channel *channel;
-  grpc_arg context_arg;
+  grpc_arg connector_arg;
   grpc_channel_args *args_copy;
+  grpc_channel_args *new_args_from_connector;
+  grpc_channel_security_connector* connector;
+  grpc_mdctx *mdctx;
 #define MAX_FILTERS 3
   const grpc_channel_filter *filters[MAX_FILTERS];
   int n = 0;
-  if (grpc_find_security_context_in_args(args) != NULL) {
+
+  if (grpc_find_security_connector_in_args(args) != NULL) {
     gpr_log(GPR_ERROR, "Cannot set security context in channel args.");
+    return grpc_lame_client_channel_create();
   }
 
+  if (grpc_credentials_create_security_connector(
+          creds, target, args, NULL, &connector, &new_args_from_connector) !=
+      GRPC_SECURITY_OK) {
+    return grpc_lame_client_channel_create();
+  }
+  mdctx = grpc_credentials_get_or_create_metadata_context(creds);
+
   s = gpr_malloc(sizeof(setup));
-  context_arg = grpc_security_context_to_arg(&context->base);
-  args_copy = grpc_channel_args_copy_and_add(args, &context_arg);
+  connector_arg = grpc_security_connector_to_arg(&connector->base);
+  args_copy = grpc_channel_args_copy_and_add(
+      new_args_from_connector != NULL ? new_args_from_connector : args,
+      &connector_arg);
   filters[n++] = &grpc_client_surface_filter;
   if (grpc_channel_args_is_census_enabled(args)) {
     filters[n++] = &grpc_client_census_filter;
@@ -228,13 +242,14 @@
   GPR_ASSERT(n <= MAX_FILTERS);
   channel = grpc_channel_create_from_filters(filters, n, args_copy, mdctx, 1);
   grpc_channel_args_destroy(args_copy);
+  if (new_args_from_connector != NULL) {
+    grpc_channel_args_destroy(new_args_from_connector);
+  }
 
   s->target = gpr_strdup(target);
   s->setup_callback = complete_setup;
   s->setup_user_data = grpc_channel_get_channel_stack(channel);
-  s->security_context =
-      (grpc_channel_security_context *)grpc_security_context_ref(
-          &context->base);
+  s->security_connector = connector;
   grpc_client_setup_create_and_attach(grpc_channel_get_channel_stack(channel),
                                       args, mdctx, initiate_setup, done_setup,
                                       s);
diff --git a/test/core/end2end/fixtures/chttp2_fake_security.c b/test/core/end2end/fixtures/chttp2_fake_security.c
index 047d482..929f1f5 100644
--- a/test/core/end2end/fixtures/chttp2_fake_security.c
+++ b/test/core/end2end/fixtures/chttp2_fake_security.c
@@ -38,7 +38,6 @@
 
 #include "src/core/channel/channel_args.h"
 #include "src/core/security/credentials.h"
-#include "src/core/security/security_context.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
index 16433f5..9c4086d 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
@@ -38,7 +38,6 @@
 
 #include "src/core/channel/channel_args.h"
 #include "src/core/security/credentials.h"
-#include "src/core/security/security_context.h"
 #include "src/core/support/env.h"
 #include "src/core/support/file.h"
 #include "src/core/support/string.h"
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
index 99031df..e9e1c5f 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
@@ -39,7 +39,6 @@
 #include "src/core/channel/channel_args.h"
 #include "src/core/iomgr/iomgr.h"
 #include "src/core/security/credentials.h"
-#include "src/core/security/security_context.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index d1d1ec1..1b657e3 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -313,6 +313,19 @@
                                         composite_creds);
 }
 
+void test_ssl_fake_transport_security_composite_creds_failure(void) {
+  grpc_credentials *ssl_creds =
+      grpc_ssl_credentials_create(NULL, NULL);
+  grpc_credentials *fake_transport_security_creds =
+      grpc_fake_transport_security_credentials_create();
+
+  /* 2 connector credentials: should not work. */
+  GPR_ASSERT(grpc_composite_credentials_create(
+                 ssl_creds, fake_transport_security_creds) == NULL);
+  grpc_credentials_unref(ssl_creds);
+  grpc_credentials_unref(fake_transport_security_creds);
+}
+
 static void check_ssl_oauth2_iam_composite_metadata(
     void *user_data, grpc_mdelem **md_elems, size_t num_md,
     grpc_credentials_status status) {
diff --git a/vsprojects/vs2010/grpc.vcxproj b/vsprojects/vs2010/grpc.vcxproj
index d18c33b..ce973e8 100644
--- a/vsprojects/vs2010/grpc.vcxproj
+++ b/vsprojects/vs2010/grpc.vcxproj
@@ -86,7 +86,7 @@
   <ItemGroup>
     <ClInclude Include="..\..\src\core\httpcli\format_request.h" />
     <ClInclude Include="..\..\src\core\httpcli\httpcli.h" />
-    <ClInclude Include="..\..\src\core\httpcli\httpcli_security_context.h" />
+    <ClInclude Include="..\..\src\core\httpcli\httpcli_security_connector.h" />
     <ClInclude Include="..\..\src\core\httpcli\parser.h" />
     <ClInclude Include="..\..\src\core\security\auth.h" />
     <ClInclude Include="..\..\src\core\security\base64.h" />
@@ -94,7 +94,7 @@
     <ClInclude Include="..\..\src\core\security\json_token.h" />
     <ClInclude Include="..\..\src\core\security\secure_endpoint.h" />
     <ClInclude Include="..\..\src\core\security\secure_transport_setup.h" />
-    <ClInclude Include="..\..\src\core\security\security_context.h" />
+    <ClInclude Include="..\..\src\core\security\security_connector.h" />
     <ClInclude Include="..\..\src\core\tsi\fake_transport_security.h" />
     <ClInclude Include="..\..\src\core\tsi\ssl_transport_security.h" />
     <ClInclude Include="..\..\src\core\tsi\transport_security.h" />
@@ -194,7 +194,7 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\httpcli\httpcli.c">
     </ClCompile>
-    <ClCompile Include="..\..\src\core\httpcli\httpcli_security_context.c">
+    <ClCompile Include="..\..\src\core\httpcli\httpcli_security_connector.c">
     </ClCompile>
     <ClCompile Include="..\..\src\core\httpcli\parser.c">
     </ClCompile>
@@ -208,8 +208,6 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\security\credentials_win32.c">
     </ClCompile>
-    <ClCompile Include="..\..\src\core\security\factories.c">
-    </ClCompile>
     <ClCompile Include="..\..\src\core\security\google_default_credentials.c">
     </ClCompile>
     <ClCompile Include="..\..\src\core\security\json_token.c">
@@ -218,7 +216,7 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\security\secure_transport_setup.c">
     </ClCompile>
-    <ClCompile Include="..\..\src\core\security\security_context.c">
+    <ClCompile Include="..\..\src\core\security\security_connector.c">
     </ClCompile>
     <ClCompile Include="..\..\src\core\security\server_secure_chttp2.c">
     </ClCompile>
diff --git a/vsprojects/vs2010/grpc.vcxproj.filters b/vsprojects/vs2010/grpc.vcxproj.filters
index 7774a78..7619bc1 100644
--- a/vsprojects/vs2010/grpc.vcxproj.filters
+++ b/vsprojects/vs2010/grpc.vcxproj.filters
@@ -7,7 +7,7 @@
     <ClCompile Include="..\..\src\core\httpcli\httpcli.c">
       <Filter>src\core\httpcli</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\httpcli\httpcli_security_context.c">
+    <ClCompile Include="..\..\src\core\httpcli\httpcli_security_connector.c">
       <Filter>src\core\httpcli</Filter>
     </ClCompile>
     <ClCompile Include="..\..\src\core\httpcli\parser.c">
@@ -28,9 +28,6 @@
     <ClCompile Include="..\..\src\core\security\credentials_win32.c">
       <Filter>src\core\security</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\security\factories.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\src\core\security\google_default_credentials.c">
       <Filter>src\core\security</Filter>
     </ClCompile>
@@ -43,7 +40,7 @@
     <ClCompile Include="..\..\src\core\security\secure_transport_setup.c">
       <Filter>src\core\security</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\security\security_context.c">
+    <ClCompile Include="..\..\src\core\security\security_connector.c">
       <Filter>src\core\security</Filter>
     </ClCompile>
     <ClCompile Include="..\..\src\core\security\server_secure_chttp2.c">
@@ -386,7 +383,7 @@
     <ClInclude Include="..\..\src\core\httpcli\httpcli.h">
       <Filter>src\core\httpcli</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\httpcli\httpcli_security_context.h">
+    <ClInclude Include="..\..\src\core\httpcli\httpcli_security_connector.h">
       <Filter>src\core\httpcli</Filter>
     </ClInclude>
     <ClInclude Include="..\..\src\core\httpcli\parser.h">
@@ -410,7 +407,7 @@
     <ClInclude Include="..\..\src\core\security\secure_transport_setup.h">
       <Filter>src\core\security</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\security\security_context.h">
+    <ClInclude Include="..\..\src\core\security\security_connector.h">
       <Filter>src\core\security</Filter>
     </ClInclude>
     <ClInclude Include="..\..\src\core\tsi\fake_transport_security.h">
diff --git a/vsprojects/vs2013/grpc.vcxproj b/vsprojects/vs2013/grpc.vcxproj
index 4c7f0fa..250d480 100644
--- a/vsprojects/vs2013/grpc.vcxproj
+++ b/vsprojects/vs2013/grpc.vcxproj
@@ -88,7 +88,7 @@
   <ItemGroup>
     <ClInclude Include="..\..\src\core\httpcli\format_request.h" />
     <ClInclude Include="..\..\src\core\httpcli\httpcli.h" />
-    <ClInclude Include="..\..\src\core\httpcli\httpcli_security_context.h" />
+    <ClInclude Include="..\..\src\core\httpcli\httpcli_security_connector.h" />
     <ClInclude Include="..\..\src\core\httpcli\parser.h" />
     <ClInclude Include="..\..\src\core\security\auth.h" />
     <ClInclude Include="..\..\src\core\security\base64.h" />
@@ -96,7 +96,7 @@
     <ClInclude Include="..\..\src\core\security\json_token.h" />
     <ClInclude Include="..\..\src\core\security\secure_endpoint.h" />
     <ClInclude Include="..\..\src\core\security\secure_transport_setup.h" />
-    <ClInclude Include="..\..\src\core\security\security_context.h" />
+    <ClInclude Include="..\..\src\core\security\security_connector.h" />
     <ClInclude Include="..\..\src\core\tsi\fake_transport_security.h" />
     <ClInclude Include="..\..\src\core\tsi\ssl_transport_security.h" />
     <ClInclude Include="..\..\src\core\tsi\transport_security.h" />
@@ -196,7 +196,7 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\httpcli\httpcli.c">
     </ClCompile>
-    <ClCompile Include="..\..\src\core\httpcli\httpcli_security_context.c">
+    <ClCompile Include="..\..\src\core\httpcli\httpcli_security_connector.c">
     </ClCompile>
     <ClCompile Include="..\..\src\core\httpcli\parser.c">
     </ClCompile>
@@ -210,8 +210,6 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\security\credentials_win32.c">
     </ClCompile>
-    <ClCompile Include="..\..\src\core\security\factories.c">
-    </ClCompile>
     <ClCompile Include="..\..\src\core\security\google_default_credentials.c">
     </ClCompile>
     <ClCompile Include="..\..\src\core\security\json_token.c">
@@ -220,7 +218,7 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\security\secure_transport_setup.c">
     </ClCompile>
-    <ClCompile Include="..\..\src\core\security\security_context.c">
+    <ClCompile Include="..\..\src\core\security\security_connector.c">
     </ClCompile>
     <ClCompile Include="..\..\src\core\security\server_secure_chttp2.c">
     </ClCompile>
diff --git a/vsprojects/vs2013/grpc.vcxproj.filters b/vsprojects/vs2013/grpc.vcxproj.filters
index 7774a78..7619bc1 100644
--- a/vsprojects/vs2013/grpc.vcxproj.filters
+++ b/vsprojects/vs2013/grpc.vcxproj.filters
@@ -7,7 +7,7 @@
     <ClCompile Include="..\..\src\core\httpcli\httpcli.c">
       <Filter>src\core\httpcli</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\httpcli\httpcli_security_context.c">
+    <ClCompile Include="..\..\src\core\httpcli\httpcli_security_connector.c">
       <Filter>src\core\httpcli</Filter>
     </ClCompile>
     <ClCompile Include="..\..\src\core\httpcli\parser.c">
@@ -28,9 +28,6 @@
     <ClCompile Include="..\..\src\core\security\credentials_win32.c">
       <Filter>src\core\security</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\security\factories.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\src\core\security\google_default_credentials.c">
       <Filter>src\core\security</Filter>
     </ClCompile>
@@ -43,7 +40,7 @@
     <ClCompile Include="..\..\src\core\security\secure_transport_setup.c">
       <Filter>src\core\security</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\security\security_context.c">
+    <ClCompile Include="..\..\src\core\security\security_connector.c">
       <Filter>src\core\security</Filter>
     </ClCompile>
     <ClCompile Include="..\..\src\core\security\server_secure_chttp2.c">
@@ -386,7 +383,7 @@
     <ClInclude Include="..\..\src\core\httpcli\httpcli.h">
       <Filter>src\core\httpcli</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\httpcli\httpcli_security_context.h">
+    <ClInclude Include="..\..\src\core\httpcli\httpcli_security_connector.h">
       <Filter>src\core\httpcli</Filter>
     </ClInclude>
     <ClInclude Include="..\..\src\core\httpcli\parser.h">
@@ -410,7 +407,7 @@
     <ClInclude Include="..\..\src\core\security\secure_transport_setup.h">
       <Filter>src\core\security</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\security\security_context.h">
+    <ClInclude Include="..\..\src\core\security\security_connector.h">
       <Filter>src\core\security</Filter>
     </ClInclude>
     <ClInclude Include="..\..\src\core\tsi\fake_transport_security.h">