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

# Session and Cookie Policy

> How PensionsPortal.ie manages authentication sessions and secures session cookies.

PensionsPortal.ie uses **JWT-based sessions** issued by Auth.js v5. Sessions are stored in browser cookies with strict security attributes. No server-side session store is required.

## Session Configuration

```ts theme={null}
session: {
  strategy: "jwt",
}
```

Auth.js issues a signed JWT containing the user's `id`, `role`, `brokerId`, and `employerId`. The JWT is:

* **Signed** with `AUTH_SECRET` — tamper-evident
* **Not encrypted by default** — do not put sensitive data in the JWT payload beyond what is documented in [RBAC](/security/authorization-rbac)
* **Stored in a cookie** — not in `localStorage` or `sessionStorage`

## Cookie Attributes

Auth.js sets the following attributes on the session cookie automatically:

| Attribute  | Value          | Effect                                                                         |
| ---------- | -------------- | ------------------------------------------------------------------------------ |
| `HttpOnly` | ✅              | Cookie is inaccessible to JavaScript — prevents XSS-based token theft          |
| `Secure`   | ✅ (production) | Cookie only sent over HTTPS connections                                        |
| `SameSite` | `Lax`          | Prevents CSRF in most cross-site scenarios while allowing top-level navigation |
| `Path`     | `/`            | Cookie scoped to the full application                                          |

<Note>
  In development (`NODE_ENV !== "production"`), the `Secure` flag is relaxed to allow HTTP on localhost. It is always enforced in production.
</Note>

## Session Lifetime

Auth.js defaults apply:

* **Session max age**: 30 days (rolling)
* **JWT max age**: 30 days

Sessions are re-validated on each request. If `AUTH_SECRET` is rotated, all existing sessions are immediately invalidated — they cannot be verified.

## Session Invalidation

Sessions are invalidated by:

1. **Signing out** — Auth.js deletes the session cookie
2. **JWT secret rotation** — all sessions become unverifiable
3. **Cookie expiry** — browser discards the cookie after max-age

There is no server-side session revocation list. If immediate invalidation is required (e.g., following an account compromise), rotate `AUTH_SECRET` in Vercel environment variables and redeploy.

## Cross-Site Request Forgery (CSRF)

Auth.js includes built-in CSRF protection:

* State tokens are used for OAuth flows (not applicable here, but the infrastructure is present)
* `SameSite=Lax` on the session cookie prevents most cross-site POST attacks
* The `Content-Security-Policy: form-action 'self'` header (set in `next.config.ts`) prevents forms from submitting to external domains

## XSS and Cookie Theft

The `HttpOnly` flag means that even if an XSS vulnerability were exploited, JavaScript cannot read the session cookie. Combined with the [Content Security Policy](/security/security-headers-csp-hsts), the attack surface for session theft via script injection is significantly reduced.

## Cookies Set by the Application

| Cookie Name            | Purpose                            | Duration          |
| ---------------------- | ---------------------------------- | ----------------- |
| `authjs.session-token` | Auth.js JWT session                | 30 days (rolling) |
| `authjs.csrf-token`    | CSRF protection for auth endpoints | Session           |
| `authjs.callback-url`  | Redirect target after login        | Session           |

No tracking cookies, advertising cookies, or third-party cookies are set by the application.
