← Back to all posts

SAML

SAML 2.0 in ~600 lines of Go: what we kept, what we cut

12 min

A walk through the Auth Fly SAML implementation: AuthnRequest parsing, ACS pinned to SP config, XMLDSig with SHA-256 and RS256 — and the hardening still on the runway.

SAML has a reputation as a heavy protocol. The core flow we need for an IdP is small once you draw a hard line around what is in scope.

What the IdP does

  • Serves /metadata as IdP metadata XML.
  • Accepts AuthnRequest at /sso via HTTP-Redirect binding.
  • Issues a signed SAML Response posted to the SP's ACS at /sso/complete.

Strong defaults already in place

  • ACS pinned to SP config. The Response goes to the ACS URL stored in the SP allowlist, never to a URL in the inbound request. This closes ACS substitution attacks.
  • SP lookup by allowlist. Unknown Issuer values are rejected before any further processing.
  • Signed assertions. XMLDSig with SHA-256 digest and RS256 signature, enveloped-signature transform, exclusive canonicalization.
  • Required elements. AudienceRestriction, SubjectConfirmation, NotOnOrAfter — all populated from SP config.

What is on the pre-flight checklist

  • Validate Destination when present in the AuthnRequest.
  • Reject AuthnRequests with stale IssueInstant.
  • Anti-replay cache for AuthnRequest IDs.
  • Optional verification of signed AuthnRequests when an SP opts in.

What we deliberately do not build

SAML profiles we do not need: ECP, attribute query, artifact binding. Less surface, fewer ways to misconfigure.


Auth Fly logo

Auth Fly

Open auth construction kit

About Auth Fly