sondahub / SAML test IdP and SP
SAML test identity provider and service provider
Both sides of SAML 2.0 single sign-on, free and public. An identity provider that signs any of 300 directory people into your app — with switches for what gets signed, encrypted and named, and the failures your app must refuse. And a service provider that takes what your IdP sends and checks all of it, out loud.
The identity provider
- Metadata
- https://api.sondahub.com/saml/metadata
- Entity ID
- https://api.sondahub.com/saml/metadata
- SSO URL
- https://api.sondahub.com/saml/sso
- Bindings
- HTTP-Redirect and HTTP-POST
- Logout URL
- https://api.sondahub.com/saml/slo
- Certificate
- sondahub-idp.pem
- People
- any directory user_name / probe — clara.brown, say
Give your service provider the metadata address, or the three facts above it. Then sign in from your app (SP-initiated: the IdP shows a sign-in page) or start from the IdP with https://api.sondahub.com/saml/sso?acs=<your ACS URL>&audience=<your entity ID> (IdP-initiated).
Shape the answer
The sign-in page has a switch for each of these, and each is also a query parameter on the SSO URL — so a test suite can ask for exactly the response it needs to handle:
| Option | Values |
|---|---|
sign | both (default), assertion, response, none |
nameid | request (what the SP asked for), email, persistent, transient, unspecified |
attrs | basic (uid, email, firstName, lastName, groups…), claims (Microsoft claim URIs), oid (LDAP / eduPerson OIDs) |
encrypt | none, gcm, cbc — for the test SP's certificate, or for the one in sp_metadata=<your SP metadata URL> |
outcome | success, AuthnFailed, RequestDenied, expired (an assertion past its time), tampered (a signature that no longer matches) |
The test service provider
Point the other way: register the test SP as an application in your IdP, sign in, and every response that lands on its ACS is decoded, decrypted, signature-checked and judged condition by condition — status, destination, InResponseTo, time window with clock skew, audience, recipient, subject and signatures — with the issuer, the signing certificate's fingerprint, the attributes and the raw XML underneath.
- ACS (reply) URL
- https://api.sondahub.com/saml/acs
- Entity ID
- https://api.sondahub.com/saml/sp/metadata
- Metadata
- https://api.sondahub.com/saml/sp/metadata
- Start a sign-in
- https://api.sondahub.com/saml/sp?idp=<your IdP's SSO URL>
Or close the loop with the hub's own IdP: sign in to the test SP through the sondahub IdP and try the switches — sign nothing, expire the assertion, break the signature — to see each one refused.
From a test suite
Add format=json (or Accept: application/json) and both sides answer JSON instead of pages: the IdP hands back the SAMLResponse to post, and the test SP its verdict and every check.
curl "https://api.sondahub.com/saml/sso?acs=https%3A%2F%2Fapi.sondahub.com%2Fsaml%2Facs&audience=https%3A%2F%2Fapi.sondahub.com%2Fsaml%2Fsp%2Fmetadata&user=clara.brown&auto=1&format=json"
curl -X POST https://api.sondahub.com/saml/acs \ --data-urlencode "SAMLResponse=$SAML_RESPONSE" -d format=json
Questions
Who can sign in?
Anyone in the Identity directory — 300 people at a company called Orbit Labs — by user_name (or email) with the password probe. Their attributes and groups come from the directory, so a sign-in carries a real department, title and a handful of groups. Deactivated people are refused, as they should be.
Which IdPs can I check with the test SP?
Any SAML 2.0 identity provider that can post to an ACS URL: Okta, Microsoft Entra ID, Google Workspace, Keycloak, ADFS, Auth0, OneLogin, PingFederate, Shibboleth. Configure an app with the ACS and entity ID below, sign in, and the report shows what came back.
Which signatures and encryption does it handle?
The IdP signs with RSA-SHA256 and exclusive canonicalisation — the response, the assertion or both, as you choose — and encrypts assertions with AES-256-GCM or AES-256-CBC, the key wrapped with RSA-OAEP. The test SP verifies RSA-SHA1, SHA-256 and SHA-512 signatures in exclusive or inclusive canonicalisation, and decrypts GCM and CBC with RSA-OAEP key transport; RSA 1.5 key transport, which XML Encryption 1.1 tells implementations to stop accepting, is refused.
Is anything remembered between requests?
No, and the IdP and SP are honest about it: the SP proves an InResponseTo is one of its own requests with a signed request id instead of a table, single logout is answered but has no session to end, and replayed responses cannot be detected.
Does the test SP trust any certificate?
It has to check signatures with the certificate the response carries, since it cannot know your IdP's in advance — so it shows that certificate's fingerprint in the report, marked as the hub's own or as foreign. Compare it with your IdP's. A real SP pins the certificate from its IdP's metadata and refuses any other; that is the one check left to you.
Are the keys secret?
No — they are in the source, for a playground. Never trust this IdP in anything that matters.