> ## Documentation Index
> Fetch the complete documentation index at: https://docs.play2sell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SSO (Single Sign-On)

> Your company's users sign in to SalesOS with no SalesOS password — through the identity provider you already use (OAuth 2.0 / OpenID Connect) — on any page, and come back through it when the session expires.

# SSO (Single Sign-On)

Your company's users can sign in to SalesOS **without a SalesOS password**: the identity provider your company already uses does the authentication. SalesOS receives the identity, checks that the person belongs to your company and opens the session. It covers **all of SalesOS** — home screen, leads, wallet, campaigns, ranking — and the link can take the person straight to any of those pages.

This guide is for **whoever administers your company's identity provider** (the IT team).

## Who does what

| Stage | Who |
| - | - |
| Register Play2sell as an application in your provider and send us the details | Your company |
| Connect your provider to SalesOS and return the connection name and entry link | Play2sell |
| Test in staging with a test user | Your company, with Play2sell |
| Repeat in production and share the link with your users | Your company |

## Before you start

* **Administrator** access to your identity provider (OAuth 2.0 / OpenID Connect).
* Your company already uses SalesOS and SSO access has been agreed with Play2sell.
* A test user in your provider who is **not an administrator**: administrators often get access to everything automatically, and the test would pass without proving anything.

## What your provider needs

| Requirement | Detail |
| - | - |
| Flow | *Authorization code* with a **confidential** application (with a client secret) |
| PKCE | Accept PKCE with `S256` on every authorization |
| **Userinfo** endpoint | **Required.** On every sign-in SalesOS reads the user's profile from it, with the access token |
| Stable identifier | A field that identifies the person and never changes (see [The stable identifier](#the-stable-identifier)) |
| **Email** | **Required** in the profile. Without an email the sign-in is refused |
| Name | Recommended |
| Scopes | `openid profile email` (plus any your provider requires) |

<Note>
  If your provider lets you choose how the application authenticates at the token endpoint, enable both `client_secret_post` and `client_secret_basic`.
</Note>

## Step by step

<Steps>
  <Step title="Register Play2sell in your provider">
    Create **one application per environment** (production and staging) with these settings:

    | Item | Production | Staging |
    | - | - | - |
    | Callback address (redirect URI) | `https://auth.play2sell.com/login/callback` | `https://auth-staging.play2sell.com/login/callback` |
    | Client application settings | Confidential application with a client secret, using the *authorization code* flow | Same |
    | Scopes | `openid profile email` | Same |

    **Done when:** both applications exist and each callback address is exactly as above, with no trailing slash.
  </Step>

  <Step title="Map the profile">
    Make sure **userinfo** returns the user's stable identifier, **email** and name. Note the name of each field (e.g. `sub`, `email`, `name`, or `dados.cpf`).

    **Done when:** the test user has all three fields filled in.
  </Step>

  <Step title="Assign who can sign in">
    In your provider, assign the users or groups that can sign in to SalesOS to the application. This is the step most often forgotten: without the assignment, your provider refuses the sign-in before it ever reaches SalesOS.

    **Done when:** the test user is assigned to both applications.
  </Step>

  <Step title="Send the details to Play2sell over a secure channel">
    Never as plain-text email or chat. For each environment:

    * the path to your OpenID Connect configuration (`/.well-known/openid-configuration`) or your provider's **authorization**, **token** and **userinfo** endpoints;
    * the **client ID** and **client secret**;
    * the names of the **stable identifier**, **email** and **name** fields;
    * the test user and a technical contact.

    **Done when:** Play2sell confirms receipt.
  </Step>

  <Step title="Receive the connection name and the entry link">
    Play2sell connects your provider to SalesOS in staging and returns the **connection name** and the **entry link** (see [Entry link](#entry-link)).
  </Step>

  <Step title="Test in staging">
    With the test user (not an administrator), open the staging entry link:

    | Test | Expected result |
    | - | - |
    | First sign-in, no `next` | Signs in to your provider and lands on the SalesOS home screen, already in your company |
    | Open the link again, still signed in to your provider | Gets in with nothing to type |
    | Link with `next` set to a SalesOS page (e.g. `next=%2Fleads`) | Lands straight on that page |

    **Done when:** all three results happen. If something fails, see [Troubleshooting](#troubleshooting).
  </Step>

  <Step title="Production">
    Repeat step 4 with the production application details. Once Play2sell confirms, share the production entry link with your users — in your portal, intranet or any system of yours that leads to SalesOS.
  </Step>
</Steps>

## Entry link

| Environment | Link |
| - | - |
| Production | `https://app.play2sell.com/login/sso?connection=<connection>&next=<path>` |
| Staging | `https://app-staging.play2sell.com/login/sso?connection=<connection>&next=<path>` |

Each environment has its own connection: the `connection` name in staging is the one Play2sell gives you for the staging application.

| Parameter | Required | What it is |
| - | - | - |
| `connection` | Yes | Your company's connection name, which Play2sell gives you when it is turned on |
| `next` | No | The SalesOS page the user lands on after signing in — any page, e.g. `/leads`, `/wallet`, `/ranking`, `/campanha`. Without it, the home screen opens |

<Tip>
  Some SalesOS APIs already return the entry link for the right page. The [Campaigns API](/api/integrations/campaigns#signing-in-again-through-your-company’s-provider), for example, returns `access.login_url` with the address for each environment — use it instead of building the link in your code.
</Tip>

### What happens when the user opens the link

| User's situation | Result |
| - | - |
| Already has a SalesOS session | Opens the requested page directly |
| SalesOS session expired, still signed in to your provider | Goes through your provider with nothing to type and lands on the page |
| No session anywhere | Signs in to **your** provider and lands on the page |

A user who came in this way and whose session expires **inside** SalesOS is sent back through your provider automatically, to the same page, instead of a password screen they don't have.

<Warning>
  `next` only accepts a **path inside SalesOS** (starting with `/`). A full URL, another host or a sign-in path is ignored and the user lands on the home screen.
</Warning>

## The stable identifier

It is the field that says **who the person is** from one sign-in to the next. It must not change when the user changes email. Your company picks one of these:

| Identifier | When to use it |
| - | - |
| **Your provider's internal id** | The default (usually the `sub` field) |
| **CPF or CNPJ** | Recommended when your provider has the document: on the first sign-in, SalesOS finds the person already registered with that document, even under another email, and the document is added to their record. Accepted with or without formatting (11 or 14 digits, with a valid check digit); an invalid document is refused |
| **Email** | Only when there is nothing else; changing email in your provider means becoming another person |

Namespaced fields (e.g. `https://yourcompany.com/cpf`) and nested fields (e.g. `dados.cpf`) are accepted.

## Who gets in and who is refused

Signing in through your company's provider **does not open the account of someone outside your company**. A new user comes in already tied to your company, with the default role agreed with Play2sell; role changes are made in SalesOS. The cases below are refused, each with a message that tells the user what to do:

| Situation | What the user sees |
| - | - |
| The email already has a SalesOS account tied to **another company** | "This email already has a SalesOS account" — sign in with the SalesOS login |
| It is a **Play2sell staff** account | "Use the SalesOS login" |
| The person's access in your company was **deactivated** in SalesOS | "Your access is deactivated" — talk to your manager |
| Your company's access through this path is **turned off** | "This access is turned off" |
| The connection used is **not enabled** in SalesOS | "This access is not enabled" |
| Your provider did not send the **email** | "Your company's sign-in did not send your email" |
| Your provider did not send the **identifier** | "Your company's sign-in did not send your identification" |
| The **CPF/CNPJ** sent is not valid | "The CPF or CNPJ sent is not valid" |
| Your provider's **userinfo** did not respond | "Your company's sign-in did not respond as expected" |

<Note>
  The screens themselves are in Portuguese; the table translates them.
</Note>

## Offboarding and client secret rotation

* **Someone leaves your company:** deactivate the person in your provider. Their next sign-in is refused by your provider; a session they already had open in SalesOS lasts until it expires. To cut it in SalesOS too, ask your company's SalesOS manager to deactivate their access.
* **Client secret rotation:** many providers make the secret expire (usually after 6 to 24 months). Before it expires, generate a new one and send it to Play2sell over the same secure channel, with the date for the switch, so sign-in does not stop.

## Troubleshooting

| Symptom | Likely cause | What to do |
| - | - | - |
| Your provider shows a redirect address error | The redirect URI is not exactly the one in the step 1 table | Fix the address, with no trailing slash, in the right environment |
| Your provider says the user has no access to the application | The user was not assigned to the application | Assign the user or group (step 3) |
| "Your company's sign-in did not send your email" | Email is not in userinfo, or the field name given is another one | Release the email in the profile and check the field name |
| "Your company's sign-in did not respond as expected" | Userinfo returned an error or did not respond | Check that userinfo accepts the application's access token |
| Sign-in worked and stopped for everyone | Expired client secret | Generate a new one and send it to Play2sell |

When asking Play2sell for help, send: the **time** of the attempt, the user's **email**, the **environment** (production or staging) and the error **code or text** shown on screen.

## Security

* **Authorization code with server-to-server exchange:** no identity token travels in the browser URL.
* **PKCE** on every authorization.
* The **client secret** lives only in Play2sell's authentication service; it is not stored in the SalesOS database and is never shown back on any screen.
* **Denied by default:** a sign-in through a connection that is not enabled, or from a company whose access is turned off, is refused — it never falls back to another path.

## Next steps

<CardGroup cols={2}>
  <Card title="Campaigns API" icon="gift" href="/api/integrations/campaigns">
    An API that returns the entry link ready to use (`access.login_url`)
  </Card>

  <Card title="API Keys" icon="key" href="/api/integrations/api-keys">
    Server-to-server integrations
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.