diff --git a/lib/list_all_IdP_tech_contacts.xsl b/lib/list_all_IdP_tech_contacts.xsl
new file mode 100644
index 0000000..b466891
--- /dev/null
+++ b/lib/list_all_IdP_tech_contacts.xsl
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	Copyright 2016 Internet2
+
+	Licensed under the Apache License, Version 2.0 (the "License");
+	you may not use this file except in compliance with the License.
+	You may obtain a copy of the License at
+
+		http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing, software
+	distributed under the License is distributed on an "AS IS" BASIS,
+	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	See the License for the specific language governing permissions and
+	limitations under the License.
+-->
+<!--
+	list_all_IdPs_csv.xsl
+	
+	This XSL transform takes a SAML metadata aggregate, matches on every 
+	entity descriptor with an IdP role, and produces a CSV file with the 
+	following fields:
+	
+	  1. Organization Name: md:OrganizationName
+	  2. IdP Display Name: mdui:DisplayName
+	  3. IdP Entity ID: @entityID
+	  4. Registrar ID: @registrationAuthority
+	
+	Note that either of the first two fields may be blank, in which case
+	the word "NONE" is output.
+-->
+<xsl:stylesheet version="1.0"
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+	xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
+	xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi"
+	xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui">
+
+	<!-- search-and-replace constants -->
+	<xsl:variable name="double_quote" select="'&quot;'"/>
+	<xsl:variable name="double_double_quote" select="'&quot;&quot;'"/>
+
+	<!-- output is plain text -->
+	<xsl:output method="text"/>
+
+	<!-- output the heading line -->
+	<xsl:template match="/">
+	  <xsl:text>EntityID,TechContact</xsl:text>
+	  <xsl:text>&#x0a;</xsl:text>
+	  <xsl:apply-templates/>
+	</xsl:template>
+
+	<!-- match all entity descriptors with an IdP role -->
+	<xsl:template match="//md:EntityDescriptor[md:IDPSSODescriptor]">
+
+		<!-- output the entityID -->
+		<xsl:value-of select="@entityID"/>
+		
+		<!-- output the tech contact -->
+		<xsl:text>,</xsl:text>
+		<xsl:value-of select="md:ContactPerson[@contactType='technical']/md:EmailAddress"/>
+		
+		<xsl:text>&#x0a;</xsl:text>
+	</xsl:template>
+
+	<xsl:template match="text()">
+		<!-- do nothing -->
+	</xsl:template>
+</xsl:stylesheet>