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

# Overview

> Sign your end users in and get a Client Session Token without building your own auth backend.

Portal can authenticate your end users for you. Instead of running your own login
system and calling the Custodian API to mint a Client Session Token, you point
your app at the Authentication API, the user signs in, and Portal hands your app a Client Session Token for that
user's client.

## Sign-in methods

| Method           | Value in the API   | What the user does                                     |
| ---------------- | ------------------ | ------------------------------------------------------ |
| Email magic link | `EMAIL_MAGIC_LINK` | Receives an email from your domain and clicks the link |
| Google           | `GOOGLE`           | Signs in with their Google account                     |
| Apple            | `APPLE`            | Signs in with their Apple account                      |

You choose which methods to enable, per environment. See
[Enable authentication](/resources/authentication/enable-authentication).

## What you need before you start

1. Authentication turned on for the environment, with at least one method
   enabled.
2. Your environment's **Auth Environment ID**, from
   **Authentication > Configure** in the dashboard. Every request sends it in the
   `x-portal-auth-environment-id` header.
3. At least one **Redirect URL** on the environment's allow list. This is the
   page in your app that the sign-in returns the user to.

## How authentication works

Every method follows the same three steps.

1. **Start the sign-in.** Your app asks Portal to send a magic link, or asks for
   a provider authorize URL and opens it.
2. **The user comes back to your app.** Portal redirects them to your Redirect
   URL with a single-use `token` query parameter appended.
3. **Exchange the token.** Your app posts that token to Portal and receives a
   Client Session Token.

The token in step 2 is short-lived and single-use. If it expires or has already
been exchanged, the user starts over.

### Identify with an Auth Environment ID

The Authentication API is the one Portal API that does not take a Portal API Key
or a Client Session Token. Instead, to communicate with the auth endpoints, you
should use an `AuthEnvironmentId` (obtained from the dashboard):

```bash theme={null}
curl --request GET \
  --url https://api.portalhq.io/api/v3/auth/methods \
  --header 'x-portal-auth-environment-id: <AUTH_ENVIRONMENT_ID>'
```

<Warning>
  The Auth Environment ID identifies an environment, it does not authenticate a
  caller. Treat it as public, the way you would an OAuth client ID. This is why
  Portal checks every magic link request against your Redirect URL allow list,
  your verified sending domains, and your own templates, and rate limits magic
  link sends per email address.
</Warning>

## A complete sign-in

Here is how a magic link sign-in plays out end to end. Google and Apple follow the
same shape, differing only in how the sign-in starts: instead of sending an email,
your app sends the user to the provider to consent.

```mermaid theme={null}
sequenceDiagram
    autonumber
    actor User as End user
    participant App as Your app
    participant Portal
    participant Inbox as User's inbox

    App->>Portal: Which sign-in methods are enabled?
    Portal-->>App: Enabled methods

    User->>App: Enters their email address
    App->>Portal: Send a magic link to this address
    Portal->>Inbox: Sign-in email
    Portal-->>App: Link sent

    User->>Inbox: Opens the email
    User->>App: Follows the link back to your redirect URL
    App->>Portal: Exchange the sign-in token
    Portal-->>App: Client Session Token

    App-->>User: Signed in
```

Your app never sees the user's password, because there isn't one, and it never
needs a server-side call to create the client. Portal creates the end user and
their client during the exchange.

Once your app holds the Client Session Token, it initializes a Portal SDK and
carries on as it would with any other Portal client.

If the environment requires two-factor authentication, one step is added between
the exchange and the session: Portal returns a short-lived credential instead of
the Client Session Token, and your app prompts for a code from the user's
authenticator app first. See
[Two-factor authentication](/resources/authentication/two-factor-authentication).

For the requests and responses behind each step, see
[Email magic links](/resources/authentication/email-magic-links) or the
[API reference](/api-reference/auth-methods/get-the-enabled-auth-methods).

## Tokens in the flow

| Token                   | What it is for                                                   |
| ----------------------- | ---------------------------------------------------------------- |
| `token` query parameter | Proves a sign-in completed. Exchanged for a session. Single use. |
| `userJwt`               | Authorizes the two-factor step, when required. Single use.       |
| `clientSessionToken`    | Authenticates the client against the Portal APIs and SDKs.       |

The first two are short-lived. Once either is used or expires, the user has to
sign in again.

The Client Session Token behaves the same as any other Portal CST, and refreshes
itself on every authenticated request, so an active user's session stays alive
without extra calls. See
[Authentication and API Keys](/resources/authentication-and-api-keys) for the
details.

One difference is worth calling out. Normally, when a CST finally expires, your
backend mints a replacement with your Portal API Key. With Portal-managed
authentication the end user just signs in again, and that sign-in issues a fresh
Client Session Token. No Portal API Key and no backend call are involved.

## Wallet creation

The **Auto-create wallet** setting is reported back to your app by
`GET /auth/methods` as `autoCreateWallet`. It is a signal for your app and the Portal SDKs, not
something the Portal API acts on.

## How this compares to other Portal credentials

* **Portal API Key.** Your server-side key, used against the Custodian API to
  create clients and mint session tokens yourself. Unchanged, and still the right
  choice if you already run your own login. See
  [Authentication and API Keys](/resources/authentication-and-api-keys).
* **Web OTP and `authUrl`.** The existing way to authenticate a Web SDK user,
  where your backend requests a one-time password for a client it already
  created. See [Web authentication methods](/sdks/web/guide/web-authentication-methods).
* **Portal-managed authentication.** What this section covers. Portal identifies
  the user and creates the client, so you do not need a login system or a
  server-side call for first sign-in.

## Next steps

<Card title="Enable authentication" icon="toggle-on" href="/resources/authentication/enable-authentication">
  Turn authentication on for an environment and configure its settings.
</Card>

<Card title="Email magic links" icon="envelope" href="/resources/authentication/email-magic-links">
  Verify a sending domain, build an email template, and send magic links.
</Card>

<Card title="Google OAuth" icon="google" href="/resources/authentication/google-oauth">
  Create a Google OAuth client and connect it to Portal.
</Card>

<Card title="Apple OAuth" icon="apple" href="/resources/authentication/apple-oauth">
  Set up Sign in with Apple and connect it to Portal.
</Card>

<Card title="API reference" icon="code" href="/api-reference/auth-methods/get-the-enabled-auth-methods">
  Full reference for every Authentication API endpoint.
</Card>
