# Authentication in Sandboxes

Handle auth when Haystack runs your app in a cloud sandbox.

## Overview

Verification sandboxes need to access your app as if logged in. Without auth config, you'll see login screens instead of actual features.

## Strategy Overview

| Layer | Strategy | Complexity | Best For |
|-------|----------|------------|----------|
| 1 | Bypass | Simplest | Apps with dev mode / SKIP_AUTH flag |
| 2 | Fixture | Easy | Apps that check auth via API call |
| 3 | Token | Medium | Need real session state |
| 4 | Test Account | Complex | Testing actual login flows |

**Recommendation**: Start with Bypass + Fixture (layers 1-2).

## Layer 1: Bypass

Skip auth via environment variable:

```json
{
  "auth": {
    "strategy": "bypass",
    "env": {
      "VITE_SKIP_AUTH": "true"
    }
  }
}
```

In your app:

```javascript
if (import.meta.env.VITE_SKIP_AUTH === 'true') {
  return { user: { id: 'test' }, isAuthenticated: true };
}
```

## Layer 2: Fixture

Mock the auth endpoint:

```json
{
  "auth": {
    "strategy": "fixture",
    "fixture": {
      "pattern": "/auth/status",
      "source": "file://fixtures/auth-status.json"
    }
  }
}
```

## Layer 3: Token Injection

Inject a real session token:

```json
{
  "auth": {
    "strategy": "token",
    "token": {
      "type": "cookie",
      "name": "session",
      "value": "$SESSION_TOKEN"
    }
  }
}
```

Store the token:

```bash
npx -y @haystackeditor/cli@latest secrets set SESSION_TOKEN "abc123..."
```

## Layer 4: Test Account

Automate login flow:

```json
{
  "auth": {
    "strategy": "test_account",
    "test_account": {
      "username": "$TEST_USERNAME",
      "password": "$TEST_PASSWORD",
      "login_url": "/login",
      "steps": [
        { "action": "type", "selector": "input[name=email]", "value": "$TEST_USERNAME" },
        { "action": "type", "selector": "input[name=password]", "value": "$TEST_PASSWORD" },
        { "action": "click", "selector": "button[type=submit]" }
      ]
    }
  }
}
```

## Fallback Strategies

Configure fallback for when primary fails:

```json
{
  "auth": {
    "strategy": "token",
    "token": { ... },
    "fallback": "fixture",
    "fixture": { ... }
  }
}
```

## Per-Flow Overrides

Different auth per flow:

```json
{
  "auth": { "strategy": "bypass" },
  "flows": [
    { "name": "Dashboard", "steps": [...] },
    {
      "name": "Login E2E",
      "auth": { "strategy": "test_account", ... },
      "steps": [...]
    }
  ]
}
```

## Security Notes

- Never commit secrets - use `haystack secrets set`
- Use test accounts only - not real credentials
- Tokens expire - use fallback strategy
- Test accounts should only exist in staging
