diff --git a/contrib/postgres_fdw/Makefile b/contrib/postgres_fdw/Makefile
index c1b0cad453..2113fa8028 100644
--- a/contrib/postgres_fdw/Makefile
+++ b/contrib/postgres_fdw/Makefile
@@ -7,7 +7,8 @@ OBJS = \
 	deparse.o \
 	option.o \
 	postgres_fdw.o \
-	shippable.o
+	shippable.o \
+	gss_proxy.o
 PGFILEDESC = "postgres_fdw - foreign data wrapper for PostgreSQL"
 
 PG_CPPFLAGS = -I$(libpq_srcdir)
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 82aa14a65d..e5e5f534ae 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -333,6 +333,9 @@ make_new_connection(ConnCacheEntry *entry, UserMapping *user)
 		 entry->conn, server->servername, user->umid, user->userid);
 }
 
+extern char* get_gss_proxy_cred();
+extern bool has_gss_proxy_cred();
+
 /*
  * Connect to remote server using specified server and user mapping properties.
  */
@@ -349,14 +352,16 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 		const char **keywords;
 		const char **values;
 		int			n;
+		char *gss_proxy_cred_addr;
 
 		/*
 		 * Construct connection params from generic options of ForeignServer
 		 * and UserMapping.  (Some of them might not be libpq options, in
-		 * which case we'll just waste a few array slots.)  Add 3 extra slots
-		 * for fallback_application_name, client_encoding, end marker.
+		 * which case we'll just waste a few array slots.)  Add 4 extra slots
+		 * for fallback_application_name, client_encoding, end marker,
+		 * gss_proxy_cred.
 		 */
-		n = list_length(server->options) + list_length(user->options) + 3;
+		n = list_length(server->options) + list_length(user->options) + 4;
 		keywords = (const char **) palloc(n * sizeof(char *));
 		values = (const char **) palloc(n * sizeof(char *));
 
@@ -376,6 +381,14 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 		values[n] = GetDatabaseEncodingName();
 		n++;
 
+		gss_proxy_cred_addr = get_gss_proxy_cred();
+		if (gss_proxy_cred_addr != NULL)
+		{
+			keywords[n] = "gss_proxy_cred";
+			values[n] = gss_proxy_cred_addr;
+			n++;
+		}
+
 		keywords[n] = values[n] = NULL;
 
 		/* verify the set of connection parameters */
@@ -476,6 +489,9 @@ UserMappingPasswordRequired(UserMapping *user)
 {
 	ListCell   *cell;
 
+	if (has_gss_proxy_cred())
+		return false;
+
 	foreach(cell, user->options)
 	{
 		DefElem    *def = (DefElem *) lfirst(cell);
diff --git a/contrib/postgres_fdw/gss_proxy.c b/contrib/postgres_fdw/gss_proxy.c
new file mode 100644
index 0000000000..1f016c54fc
--- /dev/null
+++ b/contrib/postgres_fdw/gss_proxy.c
@@ -0,0 +1,25 @@
+#include <gssapi/gssapi.h>
+
+#include "postgres.h"
+#include "miscadmin.h"
+#include "libpq/libpq-be.h"
+
+bool has_gss_proxy_cred()
+{
+	return MyProcPort->gss != NULL && MyProcPort->gss->proxy != NULL;
+}
+
+/* ugly hack to pass the gss proxy credential from backend Port to frontend libpq. */
+char* get_gss_proxy_cred()
+{
+	char* addr = NULL;
+	if (MyProcPort->gss)
+	{
+		if (MyProcPort->gss->proxy)
+		{
+			addr = palloc(sizeof(void*) + 3);
+			sprintf(addr, "%p", MyProcPort->gss->proxy);
+		}
+	}
+	return addr;
+}
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 8cc23ef7fb..2cb3e3b435 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -935,12 +935,17 @@ pg_GSS_recvauth(Port *port)
 	}
 
 	/*
-	 * We accept any service principal that's present in our keytab. This
-	 * increases interoperability between kerberos implementations that see
-	 * for example case sensitivity differently, while not really opening up
-	 * any vector of attack.
+	 * Acquire default credential with GSS_C_BOTH. Comprare to using
+	 * GSS_C_NO_CREDENTIAL, this allows us to also acquire a proxy
+	 * credential, which can be used in postgres_fdw as for delegation.
 	 */
-	port->gss->cred = GSS_C_NO_CREDENTIAL;
+	maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME, 0,
+			NULL, GSS_C_BOTH, &port->gss->cred, NULL, NULL);
+	if (maj_stat != GSS_S_COMPLETE)
+	{
+		pg_GSS_error(_("gss_acquire_cred failed"), maj_stat, min_stat);
+		return STATUS_ERROR;
+	}
 
 	/*
 	 * Initialize sequence with an empty context
@@ -997,7 +1002,7 @@ pg_GSS_recvauth(Port *port)
 										  &port->gss->outbuf,
 										  &gflags,
 										  NULL,
-										  NULL);
+										  &port->gss->proxy);
 
 		/* gbuf no longer used */
 		pfree(buf.data);
diff --git a/src/backend/libpq/be-secure-gssapi.c b/src/backend/libpq/be-secure-gssapi.c
index 316ca65db5..4a130f8d0f 100644
--- a/src/backend/libpq/be-secure-gssapi.c
+++ b/src/backend/libpq/be-secure-gssapi.c
@@ -536,6 +536,19 @@ secure_open_gssapi(Port *port)
 		}
 	}
 
+	/*
+	 * Acquire default credential with GSS_C_BOTH. Comprare to using
+	 * GSS_C_NO_CREDENTIAL, this allows us to also acquire a proxy
+	 * credential, which can be used in postgres_fdw as for delegation.
+	 */
+	major = gss_acquire_cred(&minor, GSS_C_NO_NAME, 0,
+			NULL, GSS_C_BOTH, &port->gss->cred, NULL, NULL);
+	if (major != GSS_S_COMPLETE)
+	{
+		pg_GSS_error(_("gss_acquire_cred failed"), major, minor);
+		return -1;
+	}
+
 	while (true)
 	{
 		ssize_t		ret;
@@ -585,10 +598,10 @@ secure_open_gssapi(Port *port)
 
 		/* Process incoming data.  (The client sends first.) */
 		major = gss_accept_sec_context(&minor, &port->gss->ctx,
-									   GSS_C_NO_CREDENTIAL, &input,
+									   port->gss->cred, &input,
 									   GSS_C_NO_CHANNEL_BINDINGS,
 									   &port->gss->name, NULL, &output, NULL,
-									   NULL, NULL);
+									   NULL, &port->gss->proxy);
 		if (GSS_ERROR(major))
 		{
 			pg_GSS_error(_("could not accept GSSAPI security context"),
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index 02015efe13..6efaf75bfd 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -95,6 +95,8 @@ typedef struct
 								 * GSSAPI auth was not used */
 	bool		auth;			/* GSSAPI Authentication used */
 	bool		enc;			/* GSSAPI encryption in use */
+
+	gss_cred_id_t proxy;
 #endif
 } pg_gssinfo;
 #endif
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 3421ed4685..70da371366 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -62,6 +62,7 @@ pg_GSS_continue(PGconn *conn, int payloadlen)
 				lmin_s;
 	gss_buffer_desc ginbuf;
 	gss_buffer_desc goutbuf;
+	gss_cred_id_t proxy;
 
 	/*
 	 * On first call, there's no input token. On subsequent calls, read the
@@ -93,9 +94,15 @@ pg_GSS_continue(PGconn *conn, int payloadlen)
 		ginbuf.length = 0;
 		ginbuf.value = NULL;
 	}
+	proxy = GSS_C_NO_CREDENTIAL;
+	if (conn->gssproxycred)
+	{
+		if (1 != sscanf(conn->gssproxycred, "%p", &proxy))
+			proxy = GSS_C_NO_CREDENTIAL;
+	}
 
 	maj_stat = gss_init_sec_context(&min_stat,
-									GSS_C_NO_CREDENTIAL,
+									proxy,
 									&conn->gctx,
 									conn->gtarg_nam,
 									GSS_C_NO_OID,
@@ -1307,4 +1314,4 @@ PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user,
 							 libpq_gettext("out of memory\n"));
 
 	return crypt_pwd;
-}
+}
\ No newline at end of file
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index e950b41374..25ac862dc6 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -335,6 +335,10 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
 		"GSS-library", "", 7,	/* sizeof("gssapi") == 7 */
 	offsetof(struct pg_conn, gsslib)},
 
+	{"gss_proxy_cred", "PGGSSPROXYCRED", NULL, NULL,
+		"GSS proxy credential", "", 19, /* sizeof("0x0123456789abcdef") */
+	offsetof(struct pg_conn, gssproxycred)},
+
 	{"replication", NULL, NULL, NULL,
 		"Replication", "D", 5,
 	offsetof(struct pg_conn, replication)},
@@ -4116,6 +4120,8 @@ freePGconn(PGconn *conn)
 		free(conn->krbsrvname);
 	if (conn->gsslib)
 		free(conn->gsslib);
+	if (conn->gssproxycred)
+		free(conn->gssproxycred);
 	if (conn->connip)
 		free(conn->connip);
 	/* Note that conn->Pfdebug is not ours to close or free */
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index e9f214b61b..120d13f03f 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -390,6 +390,7 @@ struct pg_conn
 	char	   *krbsrvname;		/* Kerberos service name */
 	char	   *gsslib;			/* What GSS library to use ("gssapi" or
 								 * "sspi") */
+	char       *gssproxycred;   /* proxy/delegation credential address(hex string) */
 	char	   *ssl_min_protocol_version;	/* minimum TLS protocol version */
 	char	   *ssl_max_protocol_version;	/* maximum TLS protocol version */
 	char	   *target_session_attrs;	/* desired session properties */
