> For the complete documentation index, see [llms.txt](https://docs.kangal.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kangal.dev/authentication/auth.md).

# Login and account security

Kangal supports password sign-in, one-time email codes, configured OAuth providers, and tenant-specific enterprise SSO. Every successful login creates a tenant-scoped user session. The tenant and role carried by that session are used for all subsequent authorization checks.

Machine automation uses a different credential type. See [Admin API tokens](/authentication/api-tokens.md) instead of reusing a user access token.

## Choose a sign-in method

| Method                                          | When it appears                                                | Account behavior                                                                  |
| ----------------------------------------------- | -------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| Username or email and password                  | Local login is enabled                                         | Signs in an existing active account.                                              |
| Email code                                      | Outbound email is configured                                   | Sends a six-digit, one-time code to one uniquely matching active account.         |
| Google, GitHub, Microsoft, or generic OAuth SSO | The operator configured that provider                          | Links a matching account or provisions one when provider signup policy allows it. |
| Enterprise SSO                                  | An admin assigned the email domain to an OIDC or SAML provider | Uses that organization's invitation or JIT policy.                                |
| Organization invitation                         | An admin issued an unexpired invitation                        | Creates the invited tenant account, then signs the user in.                       |

## Operator requirements

* Configure the public API and console origins before enabling OAuth or enterprise SSO. Redirects outside the approved origin list are rejected.
* Run every API replica with the same JWT signing configuration and use a shared Redis service for sessions, refresh tokens, login challenges, and callback state. A replica-local cache is not a substitute for this shared state.
* Set a persistent production signing secret. During key rotation, deploy the new key and the approved previous verification keys consistently to all replicas.
* Verify SMTP delivery before offering email-code login or password recovery. The login page shows only methods whose required configuration is ready.

## Sign in from the console

Open `/<locale>/login`, for example `/en/login` or `/tr/login`.

### Password

1. Select **Password** when both local methods are available.
2. Enter the username or email and password.
3. Kangal resolves the account and its tenant, creates a session, then opens the requested console page.

Usernames and email addresses can exist in more than one tenant. A login without an explicit tenant succeeds only when the identifier resolves to one account. If the same email or username is ambiguous, use the account's unique email or ask an administrator to confirm the organization context. API clients can send `tenant_id` in the login body or `X-Tenant-ID` on the login request.

### One-time email code

1. Select **Email code**.
2. Enter the account email and select **Send code**.
3. Enter the six-digit code before it expires.

The request response is deliberately the same for known and unknown addresses, so it does not disclose whether an account exists. Codes are one-time, have a configured expiry, enforce a resend interval and attempt limit, and are rate limited by email and client IP. Email-code login is available only when exactly one active Kangal account matches the email.

### OAuth

Only configured providers are returned by `GET /auth/oauth/providers` and shown on the login page. Google and GitHub require a verified provider email. A provider identity is linked by provider subject; a matching email can link to an existing account inside the configured tenant. New-account creation, default tenant selection, and optional personal-tenant provisioning are operator policies for each provider.

OAuth state is single-use and expires after five minutes. Redirects are accepted only for configured console origins or safe relative paths. Cancelled consent, expired state, unverified email, account-link conflicts, and inactive accounts return the user to login with a bounded error code; provider tokens and authorization codes are not displayed in the console.

### Enterprise SSO

Enter the work email in the **SSO** field. Kangal finds the enabled provider by the email domain and redirects to the organization's OIDC or SAML identity provider. The account must already exist, have a pending invitation, or be eligible for JIT provisioning. See [SSO and SCIM](/organizations-and-access/sso-scim.md).

## Session lifecycle

| Item                                | Behavior                                                                                                  |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------- |
| Access token                        | Bearer JWT, 60 minutes by default; contains user, tenant, role, and session ID.                           |
| Refresh token                       | Seven days by default; stored server-side as a hash and rotated on every successful refresh.              |
| Browser storage                     | Access and refresh tokens are kept in memory and browser `sessionStorage`, not persistent `localStorage`. |
| Automatic refresh                   | A `401` triggers one shared refresh attempt; waiting requests reuse the new access token.                 |
| Parallel login                      | Multiple access sessions can remain valid at the same time.                                               |
| Logout                              | Ends the current access session and revokes refresh tokens for that user in the tenant.                   |
| Password reset or SCIM deactivation | Revokes all access sessions and refresh tokens for that user in the tenant.                               |

The old refresh token cannot be replayed after rotation. If refresh fails, the console clears its local session and returns to login. Logging out one browser does not immediately remove every already-issued parallel access token; those sessions expire naturally unless an administrator deactivates the user or the user completes a password reset.

Role changes are reflected in newly issued access tokens. An existing access token can carry its previous role until it expires or its session is revoked.

## API workflow

Use placeholders or environment variables; never put a real password or token in documentation, source control, shell history, or support messages.

```bash
export KANGAL_URL='https://api.example.com'

curl --request POST "$KANGAL_URL/auth/login" \
  --header 'Content-Type: application/json' \
  --data '{
    "username": "operator@example.com",
    "password": "<password>",
    "tenant_id": "acme"
  }'
```

The response contains `access_token`, `refresh_token`, `token_type`, and `expires_in`. Use the access token as a bearer credential:

```bash
curl "$KANGAL_URL/auth/me" \
  --header 'Authorization: Bearer <access-token>'
```

Rotate the refresh token before the access token expires:

```bash
curl --request POST "$KANGAL_URL/auth/refresh" \
  --header 'Content-Type: application/json' \
  --data '{"refresh_token":"<current-refresh-token>"}'
```

Replace both local values with the returned pair. Reusing the previous refresh token returns `401`.

To log out, send the current access token:

```bash
curl --request POST "$KANGAL_URL/auth/logout" \
  --header 'Authorization: Bearer <access-token>'
```

## Account creation and recovery

* `/auth/register` is an admin-protected account creation endpoint. Customer account creation should use an authorized admin, invitation, federation, or directory-provisioning workflow.
* Organization invitations create tenant-scoped accounts with `user`, `admin_readonly`, or `admin` role and require a password of at least 12 characters.
* Enterprise JIT and ordinary OAuth signup depend on provider policy.
* SCIM-created users start with the `user` role and a generated password.
* **Forgot password** sends a one-time code. A successful reset requires an eight-character minimum password and revokes every existing session for the account in that tenant.

## Troubleshooting

| Symptom                              | Check                                                                                                                     |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
| Password form is absent              | Local login may be disabled by the operator.                                                                              |
| Email-code option is absent          | Outbound email is not ready.                                                                                              |
| A code never arrives                 | Check spam filtering and delivery status; requesting an unknown or ambiguous email intentionally looks successful.        |
| `429` when requesting a code         | Wait for the resend interval; repeated requests are rate limited.                                                         |
| Login says the account is ambiguous  | Specify the tenant through the API or use an identifier unique across tenants.                                            |
| OAuth button is absent               | The provider is incomplete or disabled.                                                                                   |
| OAuth returns invalid state          | Start a new login; state is short-lived and single-use.                                                                   |
| Enterprise SSO provider is not found | Confirm that the provider is enabled and the email domain exactly matches a verified domain.                              |
| API repeatedly returns `401`         | Refresh once with the latest refresh token. If that fails, sign in again.                                                 |
| API returns `403`                    | Authentication succeeded, but the session role, token scope, tenant, or detailed permission does not allow the operation. |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.kangal.dev/authentication/auth.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
