diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index a6760a1400e2da2dbea9bf48ca0582b2893ba4f5..d7ed2d8ce0c7feb4d47b5de17667cfe19e54ee25 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -204,7 +204,12 @@ grpc_call_error grpc_call_set_credentials(grpc_call *call,
 #define GRPC_X509_SAN_PROPERTY_NAME "x509_subject_alternative_name"
 
 typedef struct grpc_auth_context grpc_auth_context;
-typedef struct grpc_auth_property_iterator grpc_auth_property_iterator;
+
+typedef struct grpc_auth_property_iterator {
+  const grpc_auth_context *ctx;
+  size_t index;
+  const char *name;
+} grpc_auth_property_iterator;
 
 /* value, if not NULL, is guaranteed to be NULL terminated. */
 typedef struct grpc_auth_property {
@@ -216,20 +221,19 @@ typedef struct grpc_auth_property {
 /* Returns NULL when the iterator is at the end. */
 const grpc_auth_property *grpc_auth_property_iterator_next(
     grpc_auth_property_iterator *it);
-void grpc_auth_property_iterator_destroy(grpc_auth_property_iterator *it);
 
-grpc_auth_property_iterator *grpc_auth_context_property_iterator(
+/* Iterates over the auth context. */
+grpc_auth_property_iterator grpc_auth_context_property_iterator(
     const grpc_auth_context *ctx);
 
-/* Gets the peer identity. Returns NULL if the peer is not authenticated.
-   An identity may consist of multiple values (e.g. Subject Alternative Names
-   in X509 SSL certificates). */
-grpc_auth_property_iterator *grpc_auth_context_peer_identity(
+/* Gets the peer identity. Returns an empty iterator (first _next will return
+   NULL) if the peer is not authenticated. */
+grpc_auth_property_iterator grpc_auth_context_peer_identity(
     const grpc_auth_context *ctx);
 
-/* Finds a property in the context. May return an empty iterator if no property
-   with this name was found in the context. Will return NULL on NULL input. */
-grpc_auth_property_iterator *grpc_auth_context_find_properties_by_name(
+/* Finds a property in the context. May return an empty iterator (first _next
+   will return NULL) if no property with this name was found in the context. */
+grpc_auth_property_iterator grpc_auth_context_find_properties_by_name(
     const grpc_auth_context *ctx, const char *name);
 
 /* Gets the name of the property that indicates the peer identity. Will return
@@ -237,6 +241,9 @@ grpc_auth_property_iterator *grpc_auth_context_find_properties_by_name(
 const char *grpc_auth_context_peer_identity_property_name(
     const grpc_auth_context *ctx);
 
+/* Returns 1 if the peer is authenticated, 0 otherwise. */
+int grpc_auth_context_peer_is_authenticated(const grpc_auth_context *ctx);
+
 /* Gets the auth context from the call. */
 const grpc_auth_context *grpc_call_auth_context(grpc_call *call);
 
diff --git a/src/core/channel/context.h b/src/core/channel/context.h
index 85de60d81ae01c09e3ae6e2c9faeca0cb57d529a..ac5796b9ef19fce5968790a791d56c0e86708dc3 100644
--- a/src/core/channel/context.h
+++ b/src/core/channel/context.h
@@ -44,6 +44,6 @@ typedef enum {
 typedef struct {
   void *value;
   void (*destroy)(void *);
-} grpc_call_context;
+} grpc_call_context_element;
 
 #endif /* GRPC_INTERNAL_CORE_CHANNEL_CONTEXT_H */
diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c
index 9e1198919bf9e05c71afa64032e4604298b92d81..72002ee5c203413e0368f2d3e165b1a327f2b285 100644
--- a/src/core/security/client_auth_filter.c
+++ b/src/core/security/client_auth_filter.c
@@ -125,7 +125,7 @@ static void send_security_metadata(grpc_call_element *elem,
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
   grpc_client_security_context *ctx =
-      (grpc_client_security_context *)op->contexts[GRPC_CONTEXT_SECURITY].value;
+      (grpc_client_security_context *)op->context[GRPC_CONTEXT_SECURITY].value;
   char *service_url = NULL;
   grpc_credentials *channel_creds =
       chand->security_connector->request_metadata_creds;
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index c9fcff661f5e118ca794d4f81d3b63d6b0bc3f7d..14c194c8f6f645578f29c06362a168ff2e0307f1 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -109,6 +109,8 @@ void grpc_server_security_context_destroy(void *ctx) {
 
 /* --- grpc_auth_context --- */
 
+static grpc_auth_property_iterator empty_iterator = {NULL, 0, NULL};
+
 grpc_auth_context *grpc_auth_context_create(grpc_auth_context *chained,
                                             size_t property_count) {
   grpc_auth_context *ctx = gpr_malloc(sizeof(grpc_auth_context));
@@ -138,6 +140,7 @@ void grpc_auth_context_unref(grpc_auth_context *ctx) {
       }
       gpr_free(ctx->properties);
     }
+    gpr_free(ctx);
   }
 }
 
@@ -146,19 +149,22 @@ const char *grpc_auth_context_peer_identity_property_name(
   return ctx->peer_identity_property_name;
 }
 
-grpc_auth_property_iterator *grpc_auth_context_property_iterator(
+int grpc_auth_context_peer_is_authenticated(
     const grpc_auth_context *ctx) {
-  grpc_auth_property_iterator *it;
-  if (ctx == NULL) return NULL;
-  it = gpr_malloc(sizeof(grpc_auth_property_iterator));
-  memset(it, 0, sizeof(grpc_auth_property_iterator));
-  it->ctx = ctx;
+  return ctx->peer_identity_property_name == NULL ? 0 : 1;
+}
+
+grpc_auth_property_iterator grpc_auth_context_property_iterator(
+    const grpc_auth_context *ctx) {
+  grpc_auth_property_iterator it = empty_iterator;
+  if (ctx == NULL) return it;
+  it.ctx = ctx;
   return it;
 }
 
 const grpc_auth_property *grpc_auth_property_iterator_next(
     grpc_auth_property_iterator *it) {
-  if (it == NULL) return NULL;
+  if (it == NULL || it->ctx == NULL) return NULL;
   while (it->index == it->ctx->property_count) {
     if (it->ctx->chained == NULL) return NULL;
     it->ctx = it->ctx->chained;
@@ -179,28 +185,22 @@ const grpc_auth_property *grpc_auth_property_iterator_next(
   }
 }
 
-grpc_auth_property_iterator *grpc_auth_context_find_properties_by_name(
+grpc_auth_property_iterator grpc_auth_context_find_properties_by_name(
     const grpc_auth_context *ctx, const char *name) {
-  grpc_auth_property_iterator *it;
-  if (ctx == NULL || name == NULL) return NULL;
-  it = grpc_auth_context_property_iterator(ctx);
-  it->name = gpr_strdup(name);
+  grpc_auth_property_iterator it = empty_iterator;
+  if (ctx == NULL || name == NULL) return empty_iterator;
+  it.ctx = ctx;
+  it.name = name;
   return it;
 }
 
-grpc_auth_property_iterator *grpc_auth_context_peer_identity(
+grpc_auth_property_iterator grpc_auth_context_peer_identity(
     const grpc_auth_context *ctx) {
-  if (ctx == NULL || ctx->peer_identity_property_name == NULL) return NULL;
+  if (ctx == NULL) return empty_iterator;
   return grpc_auth_context_find_properties_by_name(
       ctx, ctx->peer_identity_property_name);
 }
 
-void grpc_auth_property_iterator_destroy(grpc_auth_property_iterator *it) {
-  if (it == NULL) return;
-  if (it->name != NULL) gpr_free(it->name);
-  gpr_free(it);
-}
-
 grpc_auth_property grpc_auth_property_init_from_cstring(const char *name,
                                                         const char *value) {
   grpc_auth_property prop;
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
index 60a31777736a06822f84299a988d21fe946a2032..d8909cd6f1e29c664a70932a3f923cb7e15fc1fb 100644
--- a/src/core/security/security_context.h
+++ b/src/core/security/security_context.h
@@ -42,12 +42,6 @@
 
 /* Property names are always NULL terminated. */
 
-struct grpc_auth_property_iterator {
-  const grpc_auth_context *ctx;
-  size_t index;
-  char *name;
-};
-
 struct grpc_auth_context {
   struct grpc_auth_context *chained;
   grpc_auth_property *properties;
diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c
index 03372328edb62367db8bc3c03c21516465f96ee4..1823f758081544a4e8f9590183f0c3dc321b5277 100644
--- a/src/core/security/server_auth_filter.c
+++ b/src/core/security/server_auth_filter.c
@@ -77,17 +77,17 @@ static void init_call_elem(grpc_call_element *elem,
   /* initialize members */
   calld->unused = 0;
 
-  GPR_ASSERT(initial_op && initial_op->contexts != NULL &&
+  GPR_ASSERT(initial_op && initial_op->context != NULL &&
              chand->security_connector->auth_context != NULL &&
-             initial_op->contexts[GRPC_CONTEXT_SECURITY].value == NULL);
+             initial_op->context[GRPC_CONTEXT_SECURITY].value == NULL);
 
   /* Create a security context for the call and reference the auth context from
      the channel. */
   server_ctx = grpc_server_security_context_create();
   server_ctx->auth_context =
       grpc_auth_context_ref(chand->security_connector->auth_context);
-  initial_op->contexts[GRPC_CONTEXT_SECURITY].value = server_ctx;
-  initial_op->contexts[GRPC_CONTEXT_SECURITY].destroy =
+  initial_op->context[GRPC_CONTEXT_SECURITY].value = server_ctx;
+  initial_op->context[GRPC_CONTEXT_SECURITY].destroy =
       grpc_server_security_context_destroy;
 }
 
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index 0169ce3158823f5b48e28508f175daf05aada98f..db76c3a3b3c71fe10209e1587f05286063c109e2 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -206,7 +206,7 @@ struct grpc_call {
   received_status status[STATUS_SOURCE_COUNT];
 
   /* Contexts for various subsystems (security, tracing, ...). */
-  grpc_call_context contexts[GRPC_CONTEXT_COUNT];
+  grpc_call_context_element context[GRPC_CONTEXT_COUNT];
 
   /* Deadline alarm - if have_alarm is non-zero */
   grpc_alarm alarm;
@@ -290,7 +290,7 @@ grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq,
     initial_op.recv_state = &call->recv_state;
     initial_op.on_done_recv = call_on_done_recv;
     initial_op.recv_user_data = call;
-    initial_op.contexts = call->contexts;
+    initial_op.context = call->context;
     call->receiving = 1;
     GRPC_CALL_INTERNAL_REF(call, "receiving");
     initial_op_ptr = &initial_op;
@@ -344,8 +344,8 @@ static void destroy_call(void *call, int ignored_success) {
     grpc_mdelem_unref(c->send_initial_metadata[i].md);
   }
   for (i = 0; i < GRPC_CONTEXT_COUNT; i++) {
-    if (c->contexts[i].destroy) {
-      c->contexts[i].destroy(c->contexts[i].value);
+    if (c->context[i].destroy) {
+      c->context[i].destroy(c->context[i].value);
     }
   }
   grpc_sopb_destroy(&c->send_ops);
@@ -1048,7 +1048,7 @@ static grpc_call_error cancel_with_status(
 static void execute_op(grpc_call *call, grpc_transport_op *op) {
   grpc_call_element *elem;
   elem = CALL_ELEM_FROM_CALL(call, 0);
-  op->contexts = call->contexts;
+  op->context = call->context;
   elem->filter->start_transport_op(elem, op);
 }
 
@@ -1289,15 +1289,15 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
 
 void grpc_call_context_set(grpc_call *call, grpc_context_index elem, void *value,
                            void (*destroy)(void *value)) {
-  if (call->contexts[elem].destroy) {
-    call->contexts[elem].destroy(call->contexts[elem].value);
+  if (call->context[elem].destroy) {
+    call->context[elem].destroy(call->context[elem].value);
   }
-  call->contexts[elem].value = value;
-  call->contexts[elem].destroy = destroy;
+  call->context[elem].value = value;
+  call->context[elem].destroy = destroy;
 }
 
 void *grpc_call_context_get(grpc_call *call, grpc_context_index elem) {
-  return call->contexts[elem].value;
+  return call->context[elem].value;
 }
 
 gpr_uint8 grpc_call_is_client(grpc_call *call) { return call->is_client; }
diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h
index dd6bee8ce955c0a622d4fa26a00ebce809526763..6f8d39e352f040fff7b5adc413ba6d779d2e528b 100644
--- a/src/core/transport/transport.h
+++ b/src/core/transport/transport.h
@@ -79,7 +79,7 @@ typedef struct grpc_transport_op {
   grpc_mdstr *cancel_message;
 
   /* Indexes correspond to grpc_context_index enum values */
-  grpc_call_context *contexts;
+  grpc_call_context_element *context;
 } grpc_transport_op;
 
 /* Callbacks made from the transport to the upper layers of grpc. */
diff --git a/test/core/end2end/tests/request_response_with_payload_and_call_creds.c b/test/core/end2end/tests/request_response_with_payload_and_call_creds.c
index 8e1fb63d744457648d05362b7d07fd6072818ec4..6eae92f28cd9b11a929efd4a7e8e67a7300545c4 100644
--- a/test/core/end2end/tests/request_response_with_payload_and_call_creds.c
+++ b/test/core/end2end/tests/request_response_with_payload_and_call_creds.c
@@ -113,23 +113,19 @@ static void end_test(grpc_end2end_test_fixture *f) {
 
 static void print_auth_context(int is_client, const grpc_auth_context *ctx) {
   const grpc_auth_property *p;
-  grpc_auth_property_iterator *it;
+  grpc_auth_property_iterator it;
   gpr_log(GPR_INFO, "%s peer:", is_client ? "client" : "server");
+  gpr_log(GPR_INFO, "\tauthenticated: %s",
+          grpc_auth_context_peer_is_authenticated(ctx) ? "YES" : "NO");
   it = grpc_auth_context_peer_identity(ctx);
-  gpr_log(GPR_INFO, "\tauthenticated: %s", it != NULL ? "YES" : "NO");
-  if (it != NULL) {
-    while ((p = grpc_auth_property_iterator_next(it)) != NULL) {
-      gpr_log(GPR_INFO, "\t\t%s: %s", p->name, p->value);
-    }
-    grpc_auth_property_iterator_destroy(it);
+  while ((p = grpc_auth_property_iterator_next(&it)) != NULL) {
+    gpr_log(GPR_INFO, "\t\t%s: %s", p->name, p->value);
   }
   gpr_log(GPR_INFO, "\tall properties:");
   it = grpc_auth_context_property_iterator(ctx);
-  GPR_ASSERT(it != NULL);
-  while ((p = grpc_auth_property_iterator_next(it)) != NULL) {
+  while ((p = grpc_auth_property_iterator_next(&it)) != NULL) {
     gpr_log(GPR_INFO, "\t\t%s: %s", p->name, p->value);
   }
-  grpc_auth_property_iterator_destroy(it);
 }
 
 static void test_call_creds_failure(grpc_end2end_test_config config) {
diff --git a/test/core/security/auth_context_test.c b/test/core/security/auth_context_test.c
index 88f7522fce30fb082cc4d1b0d115d93b5876294f..54548bf1fc1c3a346db6d2e60feb684aebb34d9f 100644
--- a/test/core/security/auth_context_test.c
+++ b/test/core/security/auth_context_test.c
@@ -41,26 +41,23 @@
 
 static void test_empty_context(void) {
   grpc_auth_context *ctx = grpc_auth_context_create(NULL, 0);
-  grpc_auth_property_iterator *it;
+  grpc_auth_property_iterator it;
 
   gpr_log(GPR_INFO, __FUNCTION__);
   GPR_ASSERT(ctx != NULL);
   GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == NULL);
-  GPR_ASSERT(grpc_auth_context_peer_identity(ctx) == NULL);
+  it = grpc_auth_context_peer_identity(ctx);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
   it = grpc_auth_context_property_iterator(ctx);
-  GPR_ASSERT(it != NULL);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL);
-  grpc_auth_property_iterator_destroy(it);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
   it = grpc_auth_context_find_properties_by_name(ctx, "foo");
-  GPR_ASSERT(it != NULL);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL);
-  grpc_auth_property_iterator_destroy(it);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
   grpc_auth_context_unref(ctx);
 }
 
 static void test_simple_context(void) {
   grpc_auth_context *ctx = grpc_auth_context_create(NULL, 3);
-  grpc_auth_property_iterator *it;
+  grpc_auth_property_iterator it;
   size_t i;
 
   gpr_log(GPR_INFO, __FUNCTION__);
@@ -75,24 +72,19 @@ static void test_simple_context(void) {
       strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0);
   it = grpc_auth_context_property_iterator(ctx);
   for (i = 0; i < ctx->property_count; i++) {
-    const grpc_auth_property *p = grpc_auth_property_iterator_next(it);
+    const grpc_auth_property *p = grpc_auth_property_iterator_next(&it);
     GPR_ASSERT(p == &ctx->properties[i]);
   }
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL);
-  grpc_auth_property_iterator_destroy(it);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
 
   it = grpc_auth_context_find_properties_by_name(ctx, "foo");
-  GPR_ASSERT(it != NULL);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == &ctx->properties[2]);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL);
-  grpc_auth_property_iterator_destroy(it);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[2]);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
 
   it = grpc_auth_context_peer_identity(ctx);
-  GPR_ASSERT(it != NULL);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == &ctx->properties[0]);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == &ctx->properties[1]);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL);
-  grpc_auth_property_iterator_destroy(it);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[0]);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[1]);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
 
   grpc_auth_context_unref(ctx);
 }
@@ -100,7 +92,7 @@ static void test_simple_context(void) {
 static void test_chained_context(void) {
   grpc_auth_context *chained = grpc_auth_context_create(NULL, 2);
   grpc_auth_context *ctx = grpc_auth_context_create(chained, 3);
-  grpc_auth_property_iterator *it;
+  grpc_auth_property_iterator it;
   size_t i;
 
   gpr_log(GPR_INFO, __FUNCTION__);
@@ -117,30 +109,25 @@ static void test_chained_context(void) {
       strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0);
   it = grpc_auth_context_property_iterator(ctx);
   for (i = 0; i < ctx->property_count; i++) {
-    const grpc_auth_property *p = grpc_auth_property_iterator_next(it);
+    const grpc_auth_property *p = grpc_auth_property_iterator_next(&it);
     GPR_ASSERT(p == &ctx->properties[i]);
   }
   for (i = 0; i < chained->property_count; i++) {
-    const grpc_auth_property *p = grpc_auth_property_iterator_next(it);
+    const grpc_auth_property *p = grpc_auth_property_iterator_next(&it);
     GPR_ASSERT(p == &chained->properties[i]);
   }
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL);
-  grpc_auth_property_iterator_destroy(it);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
 
   it = grpc_auth_context_find_properties_by_name(ctx, "foo");
-  GPR_ASSERT(it != NULL);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == &ctx->properties[2]);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == &chained->properties[1]);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL);
-  grpc_auth_property_iterator_destroy(it);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[2]);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &chained->properties[1]);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
 
   it = grpc_auth_context_peer_identity(ctx);
-  GPR_ASSERT(it != NULL);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == &ctx->properties[0]);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == &ctx->properties[1]);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == &chained->properties[0]);
-  GPR_ASSERT(grpc_auth_property_iterator_next(it) == NULL);
-  grpc_auth_property_iterator_destroy(it);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[0]);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[1]);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &chained->properties[0]);
+  GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL);
 
   grpc_auth_context_unref(ctx);
 }