Skip to content

feat: okta sign in#3764

Open
e-todorovski-bm wants to merge 28 commits intosuperplanehq:mainfrom
EmilTodorovski:feat/okta-sign-in
Open

feat: okta sign in#3764
e-todorovski-bm wants to merge 28 commits intosuperplanehq:mainfrom
EmilTodorovski:feat/okta-sign-in

Conversation

@e-todorovski-bm
Copy link
Copy Markdown
Collaborator

@e-todorovski-bm e-todorovski-bm commented Mar 27, 2026

Introduces Enterprise SSO login using OKTA

IMPORTANT NOTES:

  • The CI wasnt passing until i've committed the changes for the db file (the one regenerated via db.migrate). This dropped some keys. Not sure if relevant and should be reverted.
  • There is a flag to forceAuthn. This is because on logout we are clearing only our session, not OKTA's. To clear OKTA we have to implement SLO (single logout), which is heavy both on dev, and on users side (they have to setup many more things in order to make it work), and IMO it is not needed at all. forceAuthn makes the user enter credentials every time they login, which has the same effect as logging out of OKTA. Security wise there is no change to abuse this (as far as i could tell, and it is a standard way of doing things)
  • Logging it with your SSO account logs you only to a given org. Even if there are other orgs associated to the same email, or even with the same credentials, you cannot see them, unless you logout and sign in for that org. Examples in screenshots
  • CI fails on dependency check for a (IMO) safe dependency which is transient of the SAML required libraries
Screenshot 2026-03-31 at 15 59 00 Screenshot 2026-03-31 at 15 58 41 Screenshot 2026-03-31 at 15 59 49 Screenshot 2026-03-31 at 15 59 14 Screenshot 2026-03-31 at 15 59 39

shiroyasha and others added 11 commits March 19, 2026 22:58
Signed-off-by: Igor Šarčević <igor@operately.com>
Signed-off-by: Igor Šarčević <igor@operately.com>
Signed-off-by: Igor Šarčević <igor@operately.com>
Signed-off-by: Igor Šarčević <igor@operately.com>
Signed-off-by: Igor Šarčević <igor@operately.com>
Signed-off-by: Igor Šarčević <igor@operately.com>
Signed-off-by: Igor Šarčević <igor@operately.com>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
@superplanehq-integration
Copy link
Copy Markdown

👋 Commands for maintainers:

  • /sp start - Start an ephemeral machine (takes ~30s)
  • /sp stop - Stop a running machine (auto-executed on pr close)

@e-todorovski-bm e-todorovski-bm changed the title Feat/okta sign in feat: okta sign in Mar 27, 2026
Comment thread agent/src/superplaneapi/models/organizations_okta_idp_settings.py Outdated
Comment thread db/structure.sql
Comment thread pkg/directory/scim/http.go
e-todorovski-bm and others added 11 commits March 30, 2026 15:12
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Comment thread pkg/public/server.go
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
}

json.NewEncoder(w).Encode(ssoLookupResponse{Orgs: orgs})
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SSO lookup endpoint reveals org membership without authentication

Medium Severity

The handleSSOLookup endpoint (GET /auth/sso/lookup?email=...) is publicly accessible with no authentication or rate limiting. It returns organization IDs, names, and login URLs for any email address that maps to a SCIM-provisioned user in a SAML-enabled org. An attacker can enumerate email addresses to discover which organizations exist, their names, and which users belong to them. Consider adding rate limiting or a CAPTCHA to mitigate enumeration.

Fix in Cursor Fix in Web

Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Comment thread pkg/authentication/okta_saml.go
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Signed-off-by: Emil Todorovski <emil.todorovski@brightmarbles.io>
Comment thread go.mod
github.com/crewjam/saml v0.5.1 // indirect
github.com/di-wu/parser v0.2.2 // indirect
github.com/di-wu/xsd-datetime v1.0.0 // indirect
github.com/elimity-com/scim v0.0.0-20240320110924-172bf2aee9c8 // indirect
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Directly imported dependencies marked as indirect in go.mod

Low Severity

github.com/crewjam/saml and github.com/elimity-com/scim are directly imported by new package code (pkg/authentication/okta_saml.go and pkg/directory/scim/http.go respectively) but are listed as // indirect in go.mod. Additionally, github.com/golang-jwt/jwt/v5 appears both as a direct dependency (line 17) and as an indirect dependency (line 69). Running go mod tidy would correct these classifications.

Fix in Cursor Fix in Web

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

if _, err := base64.StdEncoding.DecodeString(strings.ReplaceAll(pemStr, "\n", "")); err != nil {
return "", fmt.Errorf("not a valid PEM or base64 DER certificate")
}
return strings.ReplaceAll(pemStr, "\n", ""), nil
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Raw base64 certificate path skips X.509 validation

Medium Severity

pemToBase64DER validates the certificate as X.509 only when PEM headers are present. When input is raw base64 (no ----- prefix), it only checks that the string is valid base64, not that it represents a valid X.509 certificate. This allows arbitrary base64 data to be stored as an IdP certificate, which will then cause opaque SAML signature verification failures at login time rather than a clear error at configuration time.

Additional Locations (1)
Fix in Cursor Fix in Web

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.

2 participants