Skip to content

Repository files navigation

go-ruby-saml/saml

saml — go-ruby-saml

ci Docs License Go coverage

A pure-Go (no cgo), MRI-faithful port of Ruby's ruby-saml gem — the SAML 2.0 Service Provider toolkit exposed as OneLogin::RubySaml.

It mirrors the ruby-saml surface while standing on the pure-Go SAML ecosystem — github.com/crewjam/saml for the SAML schema types and github.com/russellhaering/goxmldsig for XML digital-signature validation — rather than reimplementing XML signing or the SAML schema from scratch. It is the SAML backend for go-embedded-ruby but is a standalone, reusable module with no dependency on the Ruby runtime.

Ruby-faithful surface

ruby-saml (OneLogin::RubySaml) this module
Settings Settingsidp_sso_target_url, idp_cert / idp_cert_fingerprint, sp_entity_id, assertion_consumer_service_url, name_identifier_format, private_key / certificate, want_assertions_signed, signature_method, digest_method
Authrequest#create Authrequest.Create — SP-initiated SSO redirect URL + deflate+base64 SAMLRequest
Response#is_valid?, #name_id, #attributes, #sessionindex, #status_code, #issuers Response
Metadata#generate Metadata.Generate — SP metadata XML
IdpMetadataParser#parse IdpMetadataParser.Parse
Logoutrequest#create, SloLogoutresponse#create Logoutrequest, SloLogoutresponse — SP-initiated SLO
ValidationError ValidationError

Response validation

Response.IsValid mirrors ruby-saml's is_valid?, collecting each failure into Errors:

  • Signature — verified against the configured idp_cert or its idp_cert_fingerprint (SHA-1 / SHA-256), via goxmldsig.
  • ConditionsNotBefore / NotOnOrAfter with allowed_clock_drift.
  • AudienceAudienceRestriction matches sp_entity_id.
  • Destination — matches assertion_consumer_service_url.
  • InResponseTo — matches the originating AuthnRequest ID.
  • Issuer — matches idp_entity_id.
  • Status / Assertion countSuccess, exactly one assertion.

All time-dependent checks read an injectable clock, so validation is deterministic and timezone-independent (the suite runs under TZ=UTC).

Example

settings := &saml.Settings{
    IdPSSOTargetURL:             "https://idp.example.com/sso",
    IdPCert:                     idpCertPEM,
    SPEntityID:                  "https://sp.example.com/metadata",
    AssertionConsumerServiceURL: "https://sp.example.com/acs",
    NameIdentifierFormat:        saml.NameIDFormatEmail,
}

// SP-initiated SSO.
authn := &saml.Authrequest{}
redirect, _ := authn.Create(settings, "" /* relayState */)

// Consume the IdP response.
resp, _ := saml.NewResponse(base64SAMLResponse, settings)
resp.ExpectedInResponseTo = authn.UUID
if resp.IsValid() {
    fmt.Println(resp.NameID(), resp.Attributes())
}

Testing

Every fixture — RSA keys, X.509 certificates, and signed SAML documents (valid, tampered, expired, wrong-audience, wrong-destination, wrong-issuer, wrong-InResponseTo) — is embedded; no network is used. The suite runs with -race and enforces 100% statement coverage across three OSes and the six supported 64-bit architectures (amd64, arm64, riscv64, loong64, ppc64le, and big-endian s390x).

GOWORK=off TZ=UTC go test -race -cover ./...

License

BSD-3-Clause — see LICENSE. Copyright (c) 2026, the go-ruby-saml/saml authors.

WebAssembly

Being pure Go (CGO=0), this library also compiles to WebAssembly — both GOOS=js GOARCH=wasm (browser / Node.js) and GOOS=wasip1 GOARCH=wasm (WASI). CI builds both targets on every push, alongside the six 64-bit native/qemu arches.

GOOS=js     GOARCH=wasm go build ./...   # browser / Node
GOOS=wasip1 GOARCH=wasm go build ./...   # WASI (wasmtime, wasmer, wasmedge, …)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages