base on Open-source dev tools for enterprise SSO. Ship SAML + SCIM support this afternoon. ![](https://i.imgur.com/OhtkhbJ.png)
<div align="center">
<h1>SSOReady</h1>
<a href="https://github.com/ssoready/ssoready-typescript"><img src="https://img.shields.io/npm/v/ssoready.svg?style=flat&color=ECDC68" /></a>
<a href="https://github.com/ssoready/ssoready-python"><img src="https://img.shields.io/pypi/v/ssoready.svg?style=flat" /></a>
<a href="https://github.com/ssoready/ssoready-go"><img src="https://img.shields.io/github/v/tag/ssoready/ssoready-go?style=flat&label=golang&color=%23007D9C" /></a>
<a href="https://github.com/ssoready/ssoready-java"><img src="https://img.shields.io/maven-central/v/com.ssoready/ssoready-java?style=flat&label=maven&color=FD8100" /></a>
<a href="https://github.com/ssoready/ssoready-csharp"><img src="https://img.shields.io/nuget/v/SSOReady.Client?style=flat&color=004880" /></a>
<a href="https://github.com/ssoready/ssoready-ruby"><img src="https://img.shields.io/gem/v/ssoready?style=flat&color=EE3F2D" /></a>
<a href="https://github.com/ssoready/ssoready-php"><img src="https://img.shields.io/packagist/v/ssoready/ssoready?style=flat&color=F28D1A" /></a>
<a href="https://github.com/ssoready/ssoready/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" /></a>
<a href="https://github.com/ssoready/ssoready/stargazers"><img src="https://img.shields.io/github/stars/ssoready/ssoready?style=flat&logo=github&color=white" /></a>
<br />
<br />
<a href="https://ssoready.com/docs/saml/saml-quickstart">SAML Quickstart</a>
<span> • </span>
<a href="https://ssoready.com/docs/scim/scim-quickstart">SCIM Quickstart</a>
<span> • </span>
<a href="https://ssoready.com">Website</a>
<span> • </span>
<a href="https://ssoready.com/docs">Docs</a>
<span> • </span>
<a href="https://ssoready.com/blog">Blog</a>
<br />
<hr />
</div>
## What is SSOReady?
[SSOReady](https://ssoready.com) ([YC
W24](https://www.ycombinator.com/companies/ssoready)) is an **open-source,
straightforward** way to add SAML and SCIM support to your product:
* **[SSOReady SAML](https://ssoready.com/docs/saml/saml-quickstart)**: Everything you need to add SAML ("Enterprise SSO") to your product today.
* **[SSOReady SCIM](https://ssoready.com/docs/scim/scim-quickstart)**: Everything you need to add SCIM ("Enterprise Directory Sync") to your product today.
* **[Self-serve Setup UI](https://ssoready.com/docs/idp-configuration/enabling-self-service-configuration-for-your-customers)**:
A hosted UI your customers use to onboard themselves onto SAML and/or
SCIM.
**With SSOReady, you're in control:**
* SSOReady can be used in *any* application, regardless of what stack you use.
We provide language-specific SDKs as thin wrappers over a [straightforward
HTTP
API](https://ssoready.com/docs/api-reference/saml/redeem-saml-access-code):
* [SSOReady-TypeScript](https://github.com/ssoready/ssoready-typescript)
* [SSOReady-Python](https://github.com/ssoready/ssoready-python)
* [SSOReady-Go](https://github.com/ssoready/ssoready-go)
* [SSOReady-Java](https://github.com/ssoready/ssoready-java)
* [SSOReady-C#](https://github.com/ssoready/ssoready-csharp)
* [SSOReady-Ruby](https://github.com/ssoready/ssoready-ruby)
* [SSOReady-PHP](https://github.com/ssoready/ssoready-php)
* SSOReady is just an authentication middleware layer. SSOReady doesn’t "own" your users or require any changes to your users database.
* You can use our cloud-hosted instance or [self-host yourself](https://ssoready.com/docs/self-hosting-ssoready), with the Enterprise plan giving you SLA'd support either way.
**SSOReady can be extended with these products, available on the [Enterprise plan](https://ssoready.com/pricing):**
* [Custom Domains & Branding](https://ssoready.com/docs/ssoready-concepts/environments#custom-domains): Run
SSOReady on a domain you control, and make your entire SAML/SCIM experience on-brand.
* [Management API](https://ssoready.com/docs/management-api): Completely automate everything about SAML
and SCIM programmatically at scale.
* [Enterprise Support](https://ssoready.com/pricing): SLA'd support, including for self-hosted deployments.
## Getting started
The fastest way to get started with SSOReady is to follow the quickstart for
what you want to add support for:
* [SAML Quickstart](https://ssoready.com/docs/saml/saml-quickstart)
* [SCIM Quickstart](https://ssoready.com/docs/scim/scim-quickstart)
Most folks implement SAML and SCIM in an afternoon. It only takes two lines of
code.
## How SSOReady works
This section provides a high-level overview of how SSOReady works, and how it's possible to implement SAML and SCIM in
just an afternoon. For a more thorough introduction, visit the [SAML
quickstart](https://ssoready.com/docs/saml/saml-quickstart) or the [SCIM
quickstart](https://ssoready.com/docs/scim/scim-quickstart).
### SAML in two lines of code
SAML (aka "Enterprise SSO") consists of two steps: an *initiation* step where you redirect your users to their corporate
identity provider, and a *handling* step where you log them in once you know who they are.
To initiate logins, you'll use SSOReady's [Get SAML Redirect
URL](https://ssoready.com/docs/api-reference/saml/get-saml-redirect-url) endpoint:
```typescript
// this is how you implement a "Sign in with SSO" button
const { redirectUrl } = await ssoready.saml.getSamlRedirectUrl({
// the ID of the organization/workspace/team (whatever you call it)
// you want to log the user into
organizationExternalId: "..."
});
// redirect the user to `redirectUrl`...
```
You can use whatever your preferred ID is for organizations (you might call them "workspaces" or "teams") as your
`organizationExternalId`. You configure those IDs inside SSOReady, and SSOReady handles keeping track of that
organization's SAML and SCIM settings.
To handle logins, you'll use SSOReady's [Redeem SAML Access
Code](https://ssoready.com/docs/api-reference/saml/redeem-saml-access-code) endpoint:
```typescript
// this goes in your handler for POST /ssoready-callback
const { email, organizationExternalId } = await ssoready.saml.redeemSamlAccessCode({
samlAccessCode: "saml_access_code_..."
});
// log the user in as `email` inside `organizationExternalId`...
```
You configure the URL for your `/ssoready-callback` endpoint in SSOReady.
### SCIM in one line of code
SCIM (aka "Enterprise directory sync") is basically a way for you to get a list of your customer's employees offline.
To get a customer's employees, you'll use SSOReady's [List SCIM
Users](https://ssoready.com/docs/api-reference/scim/list-scim-users) endpoint:
```typescript
const { scimUsers, nextPageToken } = await ssoready.scim.listScimUsers({
organizationExternalId: "my_custom_external_id"
});
// create users from each scimUser
for (const { email, deleted, attributes } of scimUsers) {
// ...
}
```
## Philosophy
We believe everyone that sells software to businesses should support enterprise
SSO. It's a huge security win for your customers.
The biggest problem with enterprise SSO is that it's way too confusing. Most
open-source SAML libraries are underdocumented messes. Every time I've tried to
implement SAML, I was constantly looking for someone to just tell me what in the
_world_ I was supposed to concretely do.
We believe that more people will implement enterprise SSO if you make it obvious
and secure by default. We are obsessed with giving every developer clarity and
security here.
Also, we believe randomly pumping up prices on security software like this is
totally unacceptable. MIT-licensing the software gives you insurance against us
ever doing that. Do whatever you want with the code. Fork us if we ever
misbehave.
## Security
If you have a security issue to report, please contact us at
[email protected].
", Assign "at most 3 tags" to the expected json: {"id":"11324","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"