Skip to content

Conversation

@timkendrick
Copy link

When initiating a SAML client flow via the /sso endpoint, the service provider object Entity ID is omitted from the initialization options, causing the underlying saml library to incorrectly use the metadata URL for the SAML server as the Entity ID.

This causes some service providers (e.g. Microsoft Entra ID) to reject the SAML authentication request, as the inferred supabase auth server metadata URL does not match the provider's Entity ID.

This change ensures the service provider is correctly initialized with the provider Entity ID during the client auth flow, while retaining the existing behavior for the server metadata endpoint.

@timkendrick timkendrick requested a review from a team as a code owner October 23, 2025 17:16
@timkendrick
Copy link
Author

timkendrick commented Oct 23, 2025

Explanation of existing incorrect behavior:

Existing service provider instantiation does not pass the EntityID option:

provider := samlsp.DefaultServiceProvider(samlsp.Options{
URL: *externalURL,
Key: a.config.SAML.RSAPrivateKey,
Certificate: a.config.SAML.Certificate,
SignRequest: true,
AllowIDPInitiated: idpInitiated,
IDPMetadata: identityProvider,
})

...which leaves opts.EntityID empty in the underlying DefaultServiceProvider instantiation:

https://github.com/crewjam/saml/blob/346540312f721498fc75e69637d9250dd89f230b/samlsp/new.go#L132-L149

...so the Entity ID is incorrectly inferred as MetadataURL:

https://github.com/crewjam/saml/blob/346540312f721498fc75e69637d9250dd89f230b/service_provider.go#L71-L72

// getSAMLServiceProvider generates a new service provider object with the
// (optionally) provided descriptor (metadata) for the identity provider.
func (a *API) getSAMLServiceProvider(identityProvider *saml.EntityDescriptor, idpInitiated bool) *saml.ServiceProvider {
func (a *API) getSAMLServiceProvider(identityProvider *saml.EntityDescriptor, entityID string, idpInitiated bool) *saml.ServiceProvider {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entityDescriptor here already should include the EntityID, maybe extract it from there instead?

Copy link
Author

@timkendrick timkendrick Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review @hf - makes sense, this was my initial instinct as well.

I made the entityID argument explicit because we currently only pass the EntityDescriptor when we're in 'client mode' (i.e. authenticating with an external provider).

This function also happens to be invoked when exposing the SAML metadata endpoint ('server mode'), in which case we want to retain the existing behavior (inferring the metadata URL).

I've updated my fix to extract the identityProvider.EntityID only if there was an identityProvider provided, falling back to the previous 'inferred metadata URL' behavior if it is nil (as it is when this function is called from the SAMLMetadata endpoint).

@coveralls
Copy link

Pull Request Test Coverage Report for Build 18756420374

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 4 of 5 (80.0%) changed or added relevant lines in 3 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.002%) to 67.549%

Changes Missing Coverage Covered Lines Changed/Added Lines %
internal/api/samlacs.go 0 1 0.0%
Totals Coverage Status
Change from base Build 18655410402: 0.002%
Covered Lines: 13447
Relevant Lines: 19907

💛 - Coveralls

@timkendrick timkendrick force-pushed the timkendrick/fix-saml-client-entity-id branch from 1e95484 to 2df8476 Compare October 29, 2025 15:59
@timkendrick timkendrick requested a review from hf October 30, 2025 17:09
@timkendrick
Copy link
Author

I've addressed your feedback @hf - let me know if there's anything else I can do to help get this over the line :)

When initiating a SAML client flow via the /sso endpoint, the service provider object Entity ID is omitted from the initialization options, causing the underlying saml library to incorrectly use the metadata URL for the SAML server as the Entity ID.

This causes some service providers (e.g. Microsoft Entra ID) to reject the SAML authentication request, as the inferred supabase auth server metadata URL does not match the provider's Entity ID.

This change ensures the service provider is correctly initialized with the provider Entity ID during the client auth flow, while retaining the existing behavior for the server metadata endpoint.
@timkendrick timkendrick force-pushed the timkendrick/fix-saml-client-entity-id branch from 2df8476 to 4062183 Compare November 4, 2025 13:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants