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

# Authentication strategies

> How to authenticate in your tests and reuse the session across runs. Compares live login, authSave/authLoad state files, and cached auth modules, with trade-offs and a recommended order.

Most tests need to be logged in before they do anything useful. There are three
ways to handle that. Reach for them in this order: stay with **live login**
while it is fast enough, then add an **`authSave` / `authLoad` state file**, and
only move to a **cached auth module** when you need it.

## 1. Live login (recommended default)

Wrap your login steps in a **module** and call it from the
[`before` section](/core-concepts/test-format#before-and-after-sections) of each
test. It logs in for real on every run, so the session is never stale and there
is nothing to invalidate.

```yaml log-in.module.yaml theme={null}
fileType: momentic/module/v2
id: log-in
name: Log in
steps:
  - type:
      text: "{{ env.USERNAME }}"
      into: Email input
  - type:
      text: "{{ env.PASSWORD }}"
      into: Password input
  - click: Log in
  - checkPageContains:
      text: Dashboard # verify the authenticated state
```

```yaml checkout.test.yaml theme={null}
fileType: momentic/test/v2
id: checkout-flow
url: https://shop.example.com
before:
  - module: ../modules/log-in.module.yaml
steps:
  - act: Add a "Gravity Blanket" to the cart and check out
  - assert: The order confirmation page is shown
```

Prefer this whenever login is quick and not rate-limited. Move to one of the
options below only when logging in on every run is too slow or trips
auth-provider rate limits.

<Warning>
  Running the test **from a step in the main body** (a common thing to do while
  editing) skips the `before` section, so the login never runs and the first
  step lands on a logged-out page. Run the **whole test** to exercise the
  `before` section. See [Before and after
  sections](/core-concepts/test-format#before-and-after-sections).
</Warning>

## 2. Save and restore a state file (`authSave` / `authLoad`)

The `authSave` and `authLoad` steps (the editor's **Save auth state** / **Load
auth state**) write and read the browser's cookies, `localStorage`, and
IndexedDB to a JSON file you manage yourself. This is the closest analog to
[Playwright's `storageState`](https://playwright.dev/docs/auth), so it is the
natural next step if you are migrating from Playwright: log in once, save the
state, and load it instead of logging in again.

```yaml checkout.test.yaml theme={null}
before:
  - authLoad: ./auth-state.json
after:
  - authSave: ./auth-state.json
```

The file is portable and version-controllable: you can generate it in a setup
step, commit a fixture, or hand it to a non-Momentic tool. The trade-off is that
you own its freshness - refresh it when the saved session expires.

## 3. Cached auth module

When you want the speed-up without managing a file, let Momentic cache the
session for you. Mark the login module as an auth module and enable caching: the
first run logs in for real, and later runs (and parallel tests sharing the same
cache key) restore the saved browser state server-side and skip the login steps
entirely.

```yaml log-in.module.yaml theme={null}
fileType: momentic/module/v2
id: log-in
name: Log in
autoAuth: true # "Treat as auth module" - save & restore cookies/localStorage/IndexedDB
defaultCacheAllInvocations: true # "Cache globally" - reuse across tests
defaultCacheKey: admin-user # parallel tests sharing this key reuse one session
defaultCacheTtl: 3600000 # expire after 1 hour (shorter than the session lifetime)
steps:
  - type:
      text: "{{ env.USERNAME }}"
      into: Email input
  - type:
      text: "{{ env.PASSWORD }}"
      into: Password input
  - click: Log in
  - checkPageContains:
      text: Dashboard # verify the authenticated state so the cache only saves on success
```

Call it from the `before` section exactly like the live-login module. This is
the fastest option at scale (parallel tests reuse one session) and Momentic
handles capture, storage, expiry, and per-key isolation for you. See
[Cache authenticated sessions](/guides/auth/cached-session) for the full
walkthrough and [Modules](/core-concepts/modules#authentication-modules) for
every cache field.

<Warning>
  Don't combine `authSave` / `authLoad` with a cached auth module for the same
  session - both save and restore state, and doing both leads to stale or
  conflicting auth. Pick one.
</Warning>

## Options and trade-offs

| Strategy                                  | When it runs                       | Trade-offs                                                                             |
| ----------------------------------------- | ---------------------------------- | -------------------------------------------------------------------------------------- |
| **Live login** (recommended)              | Every run (whole-test runs only)   | Most reliable, never stale. Logs in every run, so slower and can hit rate limits.      |
| `authSave` / `authLoad` state file        | Whenever you place the steps       | Portable JSON, like Playwright's `storageState`. You own refreshing it when it stales. |
| Cached auth module (`autoAuth` + caching) | Once per cache key, within the TTL | Fastest at scale; parallel tests reuse one session. Needs a cache key and expiry.      |

## In CI

Live login works in CI with no extra setup; provide credentials as
[secrets](/configuration/environments#secrets) (`env.USERNAME`, `env.PASSWORD`,
OTP secrets) rather than committed values. If logging in every run is too slow,
add an `authSave` / `authLoad` state file or a cached auth module; the module's
session is stored server-side alongside the
[step cache](/reliability/step-cache), so once one run logs in, other runs and
shards can reuse it within the TTL.

## SSO, 2FA, and provisioned inboxes

<Warning>
  Avoid logging in through SSO providers (Google, Facebook, GitHub). They often
  block automated browsers.
</Warning>

For one-time codes and magic links, fetch the code in a **JavaScript** step and
save it to the environment:

* [Email OTP](/guides/auth/email-otp)
* [SMS OTP](/guides/auth/sms-otp)
* [Email magic links](/guides/auth/email-link)
* [Authenticator-app codes (TOTP)](/guides/auth/otpauth)

## Related

* [Cache authenticated sessions](/guides/auth/cached-session)
* [Authentication concepts](/core-concepts/authentication)
* [Modules](/core-concepts/modules)
* [Test format: before and after sections](/core-concepts/test-format#before-and-after-sections)
