# Shared Session Cookies For Direct Auth

This guide covers the deployment shape where:

- the browser calls Athena Auth directly on an auth host such as `https://auth.formations.company`
- the main app and SSR live on a sibling subdomain such as `https://app.formations.company`
- both hosts must participate in the same `HttpOnly` session cookie
- no Next.js proxy should be required

## Supported Topology

This works when the auth host and app host are sibling subdomains under the same
registrable parent domain:

- `auth.formations.company`
- `app.formations.company`

The shared cookie domain in that case is:

```text
.formations.company
```

That cookie will be sent by the browser to controlled subdomains under the same
parent domain. It will not bridge unrelated domains such as `formations.company`
and `xbp.app`.

## Required Configuration

Set all three of these together:

```env
BASE_URL=https://auth.formations.company
AUTH_BASE_PATH=/
TRUSTED_ORIGINS=https://app.formations.company
ATHENA_AUTH_COOKIE_DOMAIN=.formations.company
```

If your `BASE_URL` host and every trusted browser origin are sibling subdomains
under the same parent domain, Athena Auth now derives the same shared cookie
domain automatically. The explicit `ATHENA_AUTH_COOKIE_DOMAIN` setting remains
available as an override when you want a different cookie boundary or need to
disable the auto-derived parent-domain default.

Equivalent YAML:

```yaml
auth:
  base_url: https://auth.formations.company
  base_path: /
  trusted_origins:
    - https://app.formations.company
  session:
    cookie_domain: .formations.company
```

## What Each Setting Does

### `BASE_URL`

This is the public origin of the auth server itself. In the direct-auth deployment,
that should be the backend host:

```text
https://auth.formations.company
```

### `TRUSTED_ORIGINS`

This is the browser-origin allowlist used by the Rust runtime for CORS and CSRF
origin checks.

For the sibling-subdomain example, it must include the app origin:

```text
https://app.formations.company
```

This allows the browser on the app origin to call the auth origin with credentials.

### `ATHENA_AUTH_COOKIE_DOMAIN`

This is the part that makes the session actually shared.

If this value is missing, the cookie is host-only and belongs only to
`auth.formations.company`.

If this value is set to `.formations.company`, the same `HttpOnly` cookie is sent to:

- `auth.formations.company`
- `app.formations.company`
- other controlled subdomains under `formations.company`

That is what lets direct browser auth calls and SSR on the sibling app host use the
same session without a proxy hop.

## Exact Cookie Shape

With the sibling-subdomain configuration above, Athena Auth emits a session cookie
in this shape:

```http
Set-Cookie: athena-auth.session-token=<token>; Path=/; Secure; HttpOnly; SameSite=Lax; Domain=.formations.company
```

The sign-out path clears the same cookie using the same domain so the browser
removes the shared session cleanly across sibling subdomains.

## Why `TRUSTED_ORIGINS` Alone Is Not Enough

`TRUSTED_ORIGINS` and `cookie_domain` solve different problems:

- `TRUSTED_ORIGINS` decides whether a browser origin may call Athena Auth with credentials.
- `cookie_domain` decides which hosts receive the session cookie.

So this failure mode is expected:

1. `https://app.formations.company` is in `TRUSTED_ORIGINS`.
2. The browser can successfully call `https://auth.formations.company/sign-in/email`.
3. Athena Auth sets a host-only cookie for `auth.formations.company`.
4. SSR on `app.formations.company` does not receive that cookie.

That is why `TRUSTED_ORIGINS` alone cannot solve sibling-subdomain shared sessions.

## SameSite Behavior

The default session cookie policy is `SameSite=Lax`.

For sibling subdomains under the same site, this is normally the correct setting.
`auth.formations.company` and `app.formations.company` are cross-origin, but they
are still same-site because they share the same registrable parent domain.

You should not need `SameSite=None` just to support direct auth between sibling
subdomains.

## Constraints

### `__Host-` Cookie Names Are Not Compatible

Shared parent-domain cookies cannot be used with a session cookie name that starts
with `__Host-`.

That prefix requires:

- `Secure`
- `Path=/`
- no `Domain` attribute

A shared cookie requires a `Domain` attribute, so those rules conflict.

### This Widens The Trust Boundary

When you set `.formations.company`, every controlled subdomain under that parent
domain becomes part of the cookie boundary.

Only use a shared cookie domain when you control that parent-domain surface.

## Troubleshooting

### Browser Sign-In Works But SSR Still Looks Logged Out

Most likely cause: `ATHENA_AUTH_COOKIE_DOMAIN` is missing or empty.

The browser can call the auth host because the origin is trusted, but the app host
still does not receive the host-only auth cookie.

### Browser Gets CORS Errors Before Auth Runs

Most likely cause: the app origin is not covered by `TRUSTED_ORIGINS`.

The cookie domain does not help with CORS. The browser request has to pass the
auth host's origin checks first.

### Startup Rejects Shared Cookie Configuration

If the runtime rejects the config, check whether the cookie name starts with
`__Host-` or whether the configured domain is invalid for shared use.

## Source Of Truth

- Cookie domain config and validation: `crates/core/src/config.rs`
- Session `Set-Cookie` construction: `crates/core/src/utils/cookie_utils.rs`
- Server env/YAML mapping: `src/bin/server.rs`
- Direct browser integration proof: `tests/axum_integration_tests.rs`
