diff --git a/modules/aggregator/config-template/aggregator.php b/modules/aggregator/config-template/aggregator.php
index ff5e4bf5ee4595b47e35031558d24a7dd85201e7..772f59a2fe82bb16fb97608a9b334c12805fafe6 100644
--- a/modules/aggregator/config-template/aggregator.php
+++ b/modules/aggregator/config-template/aggregator.php
@@ -12,6 +12,19 @@ $config = array(
 		),
 	),
 
+
+	/* Whether metadata should be signed. */
+	'sign.enable' => FALSE,
+
+	/* Private key which should be used when signing the metadata. */
+	'sign.privatekey' => 'server.key',
+
+	/* Password to decrypt private key, or NULL if the private key is unencrypted. */
+	'sign.privatekey_pass' => NULL,
+
+	/* Certificate which should be included in the signature. Should correspond to the private key. */
+	'sign.certificate' => 'server.crt',
+
 );
 
 ?>
\ No newline at end of file
diff --git a/modules/aggregator/www/index.php b/modules/aggregator/www/index.php
index 92434d3e48090d12ae9488043f374abe75cc6cff..af4fee7d86e0f83d9e761d4067259564fc99221e 100644
--- a/modules/aggregator/www/index.php
+++ b/modules/aggregator/www/index.php
@@ -103,6 +103,21 @@ foreach ($entities as $entity => $sets) {
 	$entitiesDescriptor->appendChild($xml->importNode($entityDescriptor, TRUE));
 }
 
+/* Sign the metadata if enabled. */
+if ($aggregatorConfig->getBoolean('sign.enable', FALSE)) {
+	$privateKey = $aggregatorConfig->getString('sign.privatekey');
+	$privateKeyPass = $aggregatorConfig->getString('sign.privatekey_pass', NULL);
+	$certificate = $aggregatorConfig->getString('sign.certificate');
+
+	$signer = new SimpleSAML_XML_Signer(array(
+		'privatekey' => $privateKey,
+		'privatekey_pass' => $privateKeyPass,
+		'certificate' => $certificate,
+		'id' => 'ID',
+		));
+	$signer->sign($entitiesDescriptor, $entitiesDescriptor, $entitiesDescriptor->firstChild);
+}
+
 /* Show the metadata. */
 if(array_key_exists('mimetype', $_GET)) {
 	$mimeType = $_GET['mimetype'];