getsentry / sentry

Developer-first error tracking and performance monitoring
https://sentry.io
Other
37.54k stars 4.04k forks source link

SAML SSO: support IDP initiated SAML without a first successful SP initiated SAML workflow #61522

Open dixneuf19 opened 7 months ago

dixneuf19 commented 7 months ago

Problem Statement

Hi, We recently signed a contract with Sentry to migrate our hard to maintain self-hosted Sentry to SaaS.

One of the key requirement before on-boarding any developers into the new platform is having a proper SSO in place. Our company (in the financial domain) uses IBM Security Access Manager (ISAM) as IDP provider. It does support SAML 2.0 protocol for authentication, but has also some security restrictions in place.

One of this restriction is forcing WantAuthnRequestsSigned parameter to true, which forces to sign the initial SAML request from the SP (sentry) to the IDP (ISAM). Most of SAML service provider just don't support this option : we have this issue with AWS, Datadog, Productboard and I found that Okta does not support it neither. I also found in Sentry code that is not activated on the generic SAML provider.

The main workaround we had with other SP is using "SAML IDP initiated mode", which means we don't click on "connect with SSO" in the SP website (here Sentry), but we use a special link from the IDP (here ISAM) which authenticate us and then redirect us to the SP (Sentry). While the UX is not great, this is the current workaround solution for a lot of our tools.

IDP initiated mode is supported by Sentry. However, I did not find how to setup it without making SP initiated mode working first. Indeed,

There is to my knowledge no way to activate SAML SSO without first having a succesful SP initiated SAML workflow, which will never happen in our case with the WantAuthnRequestsSigned=true option in place.

We therefore are currently stuck with a new but unusable (SSO is a hard requirement for the company) Sentry SaaS subscription.

Solution Brainstorm

There are several solution, which varying degrees of difficulties:

Product Area

Settings - Auth

getsantry[bot] commented 7 months ago

Assigning to @getsentry/support for routing ⏲️

getsantry[bot] commented 7 months ago

Routing to @getsentry/product-owners-settings-auth for triage ⏲️

leedongwei commented 7 months ago

Hello! Can you reach out to support@sentry.io? The after-sales support team will help you with the setup.

We'll probably opt to unblock you quickly with a manual setup.

dixneuf19 commented 6 months ago

Hi @leedongwei

We are already in contact with support team by mail and zendesk, and they asked us to create this issue.

Anyway, it is a way to clarify the situation for everyone. I'll ping back the support team.

leedongwei commented 6 months ago

@dixneuf19 Gotcha, I've reached out to the SE on your account. We need some info from your side, and I'll work with the Ops team to manually put it into the DB. If you can send us the info by today, I can unblock you by Mon/Tue.

waitingwu commented 6 months ago

@dixneuf19 We also encountered this issue with Sentry Self-Hosted. Did you find a way to disable ISAM signing check while Sentry not supporting it currently?

dixneuf19 commented 6 months ago

Hi @waitingwu

The solution to disable ISAM signing check has been rejected by the IDP team, since it would be a global option for all apps using the IDP, not just Sentry...

The real workaround we have (and it now works) was going through Sentry support team, which manually activated (through database operations ?) SAML, without going through the whole SAML SP iniated workflow.

Note that it seems that once SAML is activated, you can modify its parameters without going through the SP initiated workflow. It means that another workaround is adding a temporary other SAML idp to active SAML in Sentry, then configuring it with the problematic IDP.

leedongwei commented 6 months ago

@waitingwu For self-hosted, you use this script through Django shell.

from sentry.models.authprovider import AuthProvider
from sentry.models.organization import Organization

target_config = {
  "attribute_mapping": {
    "last_name": "lastName",
    "first_name": "firstName",
    "identifier": "identifier",
    "user_email": "emailAddress"
  },
  "idp": {
    "sso_url": "https://www.YOUR_DOMAIN.com/YOUR_SSO_URL",
    "entity_id": "YOUR_ENTITY_ID",
    "x509cert": "YOUR_x509_CERT",
    "slo_url": null  # Optional 
  }
}

target_org = Organization.objects.get(id=YOUR_ORG_ID, slug="YOUR_ORG_SLUG")
target_provider = AuthProvider.objects.create(
    organization_id=target_org.id, provider="saml2", config=target_config
)