# INFINI Console SAML Integration: Enterprise SSO Implementation Guide

> Implement enterprise SSO with INFINI Console SAML integration. Our guide details how to connect with SAML identity providers for seamless authentication and user management.

- Repository: [INFINI Labs/console](https://github.com/infinilabs/console)
- Tags: how-to-guide
- Published: 2026-03-04

---

**INFINI Console implements SAML 2.0 single sign-on by embedding the crewjam/saml library to create a Service Provider that authenticates against external Identity Providers, mapping SAML attributes to internal RBAC users via the [`modules/security/realm/authc/saml/main.go`](https://github.com/infinilabs/console/blob/main/modules/security/realm/authc/saml/main.go) implementation.**

INFINI Console provides enterprise-grade authentication through SAML-based SSO, allowing organizations to centralize user management with external Identity Providers. The integration leverages the standard SAML 2.0 protocol within a dedicated SAML realm, enabling seamless authentication flows while maintaining compatibility with existing identity infrastructure.

## How SAML Authentication Works in INFINI Console

The SAML integration follows the standard Service Provider (SP) initiated flow, where INFINI Console acts as the SAML SP and delegates authentication to an external Identity Provider (IdP).

### Service Provider Configuration

The SAML realm initializes in [`modules/security/realm/authc/saml/main.go`](https://github.com/infinilabs/console/blob/main/modules/security/realm/authc/saml/main.go) by loading cryptographic material and endpoint definitions. The system requires a TLS key-pair (`sessioncert` and `sessionkey`) to sign encrypted authentication cookies. Critical configuration parameters include:

- **`serverurl`**: The base URL of the INFINI Console instance acting as the SP
- **`entityId`**: A unique identifier for the Service Provider
- **`metdataurl`**: The URL where the IdP publishes its SAML metadata (e.g., `https://sso.infini.ltd/metadata`)

### Identity Provider Metadata Loading

The IdP's metadata XML contains signing certificates, SSO endpoints, and the IdP's entity ID. INFINI Console fetches this metadata from the configured `metdataurl` to establish trust. The metadata populates the `samlsp.Options.IDPMetadata` field, enabling the SP to validate assertions and redirect users to the correct authentication endpoints.

### SAML Middleware Initialization

The `samlsp.New` function constructs the middleware that handles the SAML protocol implementation:

```go
keyPair, err := tls.LoadX509KeyPair(sessioncert, sessionkey)
panicIfError(err)
keyPair.Leaf, err = x509.ParseCertificate(keyPair.Certificate[0])
panicIfError(err)

rootURL, err := url.Parse(serverurl)
panicIfError(err)

samlSP, _ := samlsp.New(samlsp.Options{
    URL:         *rootURL,
    Key:         keyPair.PrivateKey.(*rsa.PrivateKey),
    Certificate: keyPair.Leaf,
    IDPMetadata: &saml.EntityDescriptor{/* Parsed IdP metadata */},
    EntityID:    entityId,
})

```

This middleware manages SSO redirects, assertion consumer service (ACS) handling, and encrypted session cookie generation.

## Implementing SAML Routes and Session Handling

Once initialized, the SAML realm registers HTTP handlers and extracts user identity from SAML assertions.

### HTTP Route Registration

Two critical endpoints enable the SAML flow:

- **`/saml/`**: The SAML protocol endpoint where the IdP posts assertions (ACS) and where SP metadata is served
- **Protected application routes**: Handlers wrapped with `samlSP.RequireAccount` middleware that forces authentication

```go
func hello(w http.ResponseWriter, r *http.Request) {
    sess := samlsp.SessionFromContext(r.Context())
    if sess == nil {
        http.Error(w, "no session", http.StatusUnauthorized)
        return
    }
    
    if attrs, ok := sess.(samlsp.SessionWithAttributes); ok {
        fmt.Fprintf(w, "User attributes: %+v", attrs.GetAttributes())
    }
}

app := http.HandlerFunc(hello)
http.Handle("/hello", samlSP.RequireAccount(app))
http.Handle("/saml/", samlSP)

```

### Session Extraction and Attribute Mapping

After successful IdP authentication, the middleware injects a SAML session into the request context. The `samlsp.SessionFromContext` function retrieves this session, which contains the user's SAML attributes such as `email`, `uid`, and `memberOf` groups.

These attributes map to INFINI Console's internal `rbac.User` model:

```go
func mapSAMLToUser(attrs map[string][]string) *rbac.User {
    u := &rbac.User{
        Username:     attrs["uid"][0],
        Email:        attrs["mail"][0],
        AuthProvider: "saml",
    }
    
    if groups, ok := attrs["memberOf"]; ok {
        u.Roles = append(u.Roles, groups...)
    }
    return u
}

```

### Authorization Integration

The `realm.Authenticate` method (registered in [`modules/security/realm/realm.go`](https://github.com/infinilabs/console/blob/main/modules/security/realm/realm.go)) forwards the mapped user record to INFINI Console's authorization layer. This layer evaluates roles and privileges derived from SAML attributes against the configured access control policies.

The SAML realm integrates alongside native, LDAP, or other authentication providers through the modular realm initialization system defined in [`modules/security/realm/realm.go`](https://github.com/infinilabs/console/blob/main/modules/security/realm/realm.go).

## Summary

- INFINI Console implements SAML 2.0 SSO using the `crewjam/saml` library within a dedicated realm at [`modules/security/realm/authc/saml/main.go`](https://github.com/infinilabs/console/blob/main/modules/security/realm/authc/saml/main.go)
- The Service Provider configuration requires TLS certificates, a base URL, EntityID, and IdP metadata URL to establish trust
- The `samlsp.New` middleware handles SAML protocol endpoints, encrypted session cookies, and assertion validation
- Protected routes use `samlSP.RequireAccount` to enforce authentication, with user attributes extracted via `samlsp.SessionFromContext`
- SAML attributes map to the internal `rbac.User` model, enabling role-based access control integration through [`modules/security/realm/realm.go`](https://github.com/infinilabs/console/blob/main/modules/security/realm/realm.go)

## Frequently Asked Questions

### What SAML library does INFINI Console use?

INFINI Console embeds the [crewjam/saml](https://github.com/crewjam/saml) library, a widely-adopted Go implementation of the SAML 2.0 specification. This library provides the Service Provider middleware, assertion parsing, and encrypted cookie session management used in [`modules/security/realm/authc/saml/main.go`](https://github.com/infinilabs/console/blob/main/modules/security/realm/authc/saml/main.go).

### How does INFINI Console map SAML attributes to user roles?

After authentication, the code extracts SAML attributes from the session context using `samlsp.SessionFromContext` and type-asserting to `samlsp.SessionWithAttributes`. The `GetAttributes()` method returns a map of SAML assertions (such as `uid`, `mail`, and `memberOf`), which the system maps to the `rbac.User` struct fields, converting group memberships into console roles for authorization.

### What endpoints are required for SAML integration?

The integration requires two primary endpoints: `/saml/`, which serves as the Assertion Consumer Service (ACS) where the IdP posts authentication responses and where SP metadata is available, and application-specific protected endpoints (such as `/hello`) wrapped with `samlSP.RequireAccount` middleware to enforce authenticated access.

### Can INFINI Console support multiple SAML Identity Providers?

The modular architecture in [`modules/security/realm/realm.go`](https://github.com/infinilabs/console/blob/main/modules/security/realm/realm.go) allows the system to initialize multiple realm instances simultaneously. While the current sample implementation in [`modules/security/realm/authc/saml/main.go`](https://github.com/infinilabs/console/blob/main/modules/security/realm/authc/saml/main.go) demonstrates a single IdP configuration, the underlying `crewjam/saml` library and realm registration system support instantiating multiple `samlsp` middleware instances with distinct EntityIDs and metadata URLs to enable multi-tenant SAML configurations.