options.signingCert format for SAML connections

Question:

When creating a SAML connection through the Auth0 Management API, what format should the IdP signing certificate, options.signingCert, be in?

Answer:

This is a common point of confusion. The correct format is a base64 encoded PEM certificate (the PEM format already contains base64 but for this use case it is encoded again).

To create this, start with a certificate in PEM format. PEM format specifically calls for the BEGIN and END lines and line breaks after 64 characters:

-----BEGIN CERTIFICATE----- MIIDajCCAlICCQDoaf3hWk19ozANBgkqhkiG9w0BAQsFADB3MQswCQYDVQQGEwJV UzELMAkGA1UECAwCV0ExETAPBgNVBAcMCEJlbGxldnVlMQ4wDAYDVQQKDAVBdXRo MDEaMBgGA1UECwwRRGV2ZWxvcGVyIFN1cHBvcnQxHDAaBgNVBAMME0V4YW1wbGUg LSBOb3QgVmFsaWQwHhcNMjEwMTEzMTgyMzE3WhcNMjIwMTEzMTgyMzE3WjB3MQsw CQYDVQQGEwJVUzELMAkGA1UECAwCV0ExETAPBgNVBAcMCEJlbGxldnVlMQ4wDAYD VQQKDAVBdXRoMDEaMBgGA1UECwwRRGV2ZWxvcGVyIFN1cHBvcnQxHDAaBgNVBAMM E0V4YW1wbGUgLSBOb3QgVmFsaWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQC5lF+nonkHHrxChdW5qAGHppDiqRjO/BLVyAL3nKUcfJs0tvMoFHXxx0V8 xffhKbXOw0451Ua3b0CjxhCKwHsOeqZKEsq2bSlfCkXgrPUPVAyeTJLy0GF1T7EQ ioqpzp8OZikD77y3y9JGEDWgtgK7dW9AgD/ImJPhlINsEj6fiBNGi8yrTDAikFsu C+qcXLTn2OviajubIYZVRJ3t+lArqmbdv6RN39slBV79/bzj4mkEgHi4EYEUBWDv lhW0RPPpmsufDvsUA+InmWkUGGf2GFPvx+Se4GyhvJ0zDtm2SDYHuwEChZVzTVG6 71jS7Qg7KXgHeFrQauzTN5qwBH39AgMBAAEwDQYJKoZIhvcNAQELBQADggEBALjk Dm9zcgsaSBoGQH8q4elaKKQKj7d+FGxnZc9Gr/GTE1nbaSVzq/E/YOTGLw0GKp58 928ZDTmtZUH4jQg1xr4rLnVAX51J1BPOfcyG1Eb+sRPf8EWmMz3MY8VdjQoPCNPj s1yXyUnw+dwQRYkcLRkedDdv2jsoGABhfPWOuoKfHiRMQA8PrSQxiYpRbNoIQGU6 UscpbtYW7w1dFX78AP1FJu0M/VVAw7holoPHAbPTKpTxQjAdbErobSh2U+o4H4tF p9OZyaGH7TpQLahhNaUMHIsxDTVg3ki7XUJsXgtqKWH+LFFwNjROyk5zcL6LJ7Q9 XWI2zpOylvE20GZwOS0=
-----END CERTIFICATE-----

And then Base64 encode the entire thing, including the BEGIN and END lines, and line breaks:

LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURhakNDQWxJQ0NRRG9hZjNoV2sxOW96QU5CZ2txaGtpRzl3MEJBUXNGQURCM01Rc3dDUVlEVlFRR0V3SlYKVXpFTE1Ba0dBMVVFQ0F3Q1YwRXhFVEFQQmdOVkJBY01DRUpsYkd4bGRuVmxNUTR3REFZRFZRUUtEQVZCZFhSbwpNREVhTUJnR0ExVUVDd3dSUkdWMlpXeHZjR1Z5SUZOMWNIQnZjblF4SERBYUJnTlZCQU1NRTBWNFlXMXdiR1VnCkxTQk9iM1FnVm1Gc2FXUXdIaGNOTWpFd01URXpNVGd5TXpFM1doY05Nakl3TVRFek1UZ3lNekUzV2pCM01Rc3cKQ1FZRFZRUUdFd0pWVXpFTE1Ba0dBMVVFQ0F3Q1YwRXhFVEFQQmdOVkJBY01DRUpsYkd4bGRuVmxNUTR3REFZRApWUVFLREFWQmRYUm9NREVhTUJnR0ExVUVDd3dSUkdWMlpXeHZjR1Z5SUZOMWNIQnZjblF4SERBYUJnTlZCQU1NCkUwVjRZVzF3YkdVZ0xTQk9iM1FnVm1Gc2FXUXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUsKQW9JQkFRQzVsRitub25rSEhyeENoZFc1cUFHSHBwRGlxUmpPL0JMVnlBTDNuS1VjZkpzMHR2TW9GSFh4eDBWOAp4ZmZoS2JYT3cwNDUxVWEzYjBDanhoQ0t3SHNPZXFaS0VzcTJiU2xmQ2tYZ3JQVVBWQXllVEpMeTBHRjFUN0VRCmlvcXB6cDhPWmlrRDc3eTN5OUpHRURXZ3RnSzdkVzlBZ0QvSW1KUGhsSU5zRWo2ZmlCTkdpOHlyVERBaWtGc3UKQytxY1hMVG4yT3ZpYWp1YklZWlZSSjN0K2xBcnFtYmR2NlJOMzlzbEJWNzkvYnpqNG1rRWdIaTRFWUVVQldEdgpsaFcwUlBQcG1zdWZEdnNVQStJbm1Xa1VHR2YyR0ZQdngrU2U0R3lodkowekR0bTJTRFlIdXdFQ2haVnpUVkc2CjcxalM3UWc3S1hnSGVGclFhdXpUTjVxd0JIMzlBZ01CQUFFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMamsKRG05emNnc2FTQm9HUUg4cTRlbGFLS1FLajdkK0ZHeG5aYzlHci9HVEUxbmJhU1Z6cS9FL1lPVEdMdzBHS3A1OAo5MjhaRFRtdFpVSDRqUWcxeHI0ckxuVkFYNTFKMUJQT2ZjeUcxRWIrc1JQZjhFV21NejNNWThWZGpRb1BDTlBqCnMxeVh5VW53K2R3UVJZa2NMUmtlZERkdjJqc29HQUJoZlBXT3VvS2ZIaVJNUUE4UHJTUXhpWXBSYk5vSVFHVTYKVXNjcGJ0WVc3dzFkRlg3OEFQMUZKdTBNL1ZWQXc3aG9sb1BIQWJQVEtwVHhRakFkYkVyb2JTaDJVK280SDR0RgpwOU9aeWFHSDdUcFFMYWhoTmFVTUhJc3hEVFZnM2tpN1hVSnNYZ3RxS1dIK0xGRndOalJPeWs1emNMNkxKN1E5ClhXSTJ6cE95bHZFMjBHWndPUzA9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=

The PEM certificate itself you should obtain from the IdP since that certificate contains the public key for verifying signatures from the IdP. Usually you get the certificate either from the metadata or download it as a separate file.

Example:

This is a curl command with the minimum information required to create a SAML connection via the API. Add your tenant name and management API token in the appropriate places:

curl -H "Authorization: Bearer <token>" -X POST  -H "Content-Type: application/json" -d '{
        "options": {
            "signInEndpoint": "https://example.com/SAML2",
            "signingCert": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURhakNDQWxJQ0NRRG9hZjNoV2sxOW96QU5CZ2txaGtpRzl3MEJBUXNGQURCM01Rc3dDUVlEVlFRR0V3SlYKVXpFTE1Ba0dBMVVFQ0F3Q1YwRXhFVEFQQmdOVkJBY01DRUpsYkd4bGRuVmxNUTR3REFZRFZRUUtEQVZCZFhSbwpNREVhTUJnR0ExVUVDd3dSUkdWMlpXeHZjR1Z5SUZOMWNIQnZjblF4SERBYUJnTlZCQU1NRTBWNFlXMXdiR1VnCkxTQk9iM1FnVm1Gc2FXUXdIaGNOTWpFd01URXpNVGd5TXpFM1doY05Nakl3TVRFek1UZ3lNekUzV2pCM01Rc3cKQ1FZRFZRUUdFd0pWVXpFTE1Ba0dBMVVFQ0F3Q1YwRXhFVEFQQmdOVkJBY01DRUpsYkd4bGRuVmxNUTR3REFZRApWUVFLREFWQmRYUm9NREVhTUJnR0ExVUVDd3dSUkdWMlpXeHZjR1Z5SUZOMWNIQnZjblF4SERBYUJnTlZCQU1NCkUwVjRZVzF3YkdVZ0xTQk9iM1FnVm1Gc2FXUXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUsKQW9JQkFRQzVsRitub25rSEhyeENoZFc1cUFHSHBwRGlxUmpPL0JMVnlBTDNuS1VjZkpzMHR2TW9GSFh4eDBWOAp4ZmZoS2JYT3cwNDUxVWEzYjBDanhoQ0t3SHNPZXFaS0VzcTJiU2xmQ2tYZ3JQVVBWQXllVEpMeTBHRjFUN0VRCmlvcXB6cDhPWmlrRDc3eTN5OUpHRURXZ3RnSzdkVzlBZ0QvSW1KUGhsSU5zRWo2ZmlCTkdpOHlyVERBaWtGc3UKQytxY1hMVG4yT3ZpYWp1YklZWlZSSjN0K2xBcnFtYmR2NlJOMzlzbEJWNzkvYnpqNG1rRWdIaTRFWUVVQldEdgpsaFcwUlBQcG1zdWZEdnNVQStJbm1Xa1VHR2YyR0ZQdngrU2U0R3lodkowekR0bTJTRFlIdXdFQ2haVnpUVkc2CjcxalM3UWc3S1hnSGVGclFhdXpUTjVxd0JIMzlBZ01CQUFFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMamsKRG05emNnc2FTQm9HUUg4cTRlbGFLS1FLajdkK0ZHeG5aYzlHci9HVEUxbmJhU1Z6cS9FL1lPVEdMdzBHS3A1OAo5MjhaRFRtdFpVSDRqUWcxeHI0ckxuVkFYNTFKMUJQT2ZjeUcxRWIrc1JQZjhFV21NejNNWThWZGpRb1BDTlBqCnMxeVh5VW53K2R3UVJZa2NMUmtlZERkdjJqc29HQUJoZlBXT3VvS2ZIaVJNUUE4UHJTUXhpWXBSYk5vSVFHVTYKVXNjcGJ0WVc3dzFkRlg3OEFQMUZKdTBNL1ZWQXc3aG9sb1BIQWJQVEtwVHhRakFkYkVyb2JTaDJVK280SDR0RgpwOU9aeWFHSDdUcFFMYWhoTmFVTUhJc3hEVFZnM2tpN1hVSnNYZ3RxS1dIK0xGRndOalJPeWs1emNMNkxKN1E5ClhXSTJ6cE95bHZFMjBHWndPUzA9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0="
        },
        "strategy": "samlp",
        "name": "samltestconnection1"
    }' "https://<tenant>.auth0.com/api/v2/connections"