@mushi-mushi/inventory-auth-runner
A small Playwright runner that signs in to your app with the login script
in your inventory.yaml, picks the session
cookie, and saves it to your Mushi Mushi project so the crawler and synthetic
monitor can reach pages behind a login wall.
When you need it
If your inventory.yaml describes any path that requires a session
(/dashboard, /settings/*), the crawler and synthetic monitor will
get redirected to /login until they have valid auth. This package
gives you the bootstrap step that hands them a session.
Install
pnpm add -D @mushi-mushi/inventory-auth-runner
npx playwright install chromium # once, if Playwright has no Chromium on this machine yetUsage
Add a scripted auth block under app in inventory.yaml. The script is
the body of an async function that receives Playwright’s page, an env
object for your secrets, and context; the runner has already opened
base_url + login_path:
app:
id: acme-web
name: Acme web
base_url: https://app.acme.test
auth:
type: scripted
config:
login_path: /login
script: |
await page.fill('[data-testid=email]', env.TEST_USER_EMAIL)
await page.fill('[data-testid=password]', env.TEST_USER_PASSWORD)
await page.click('[data-testid=login]')
await page.waitForURL('**/dashboard')Inline scripts may not use require(, import(, process., eval( and
similar escapes, and are capped at 8 KB. For anything longer, set
script: 'js:./scripts/login.js' to a module that default-exports an
async (page, env, context) function. The path resolves against the folder
of your local inventory.yaml (--inventory <path> or
MUSHI_INVENTORY_FILE; default ./inventory.yaml, so the working
directory).
Then run:
TEST_USER_EMAIL=user@acme.test \
TEST_USER_PASSWORD=… \
MUSHI_API_KEY=mushi_… \
MUSHI_PROJECT=<project-uuid> \
npx mushi-mushi-auth refreshWithout installing, use
npx --yes -p @mushi-mushi/inventory-auth-runner mushi-mushi-auth refresh.
MUSHI_API_KEY needs the mcp:write scope. MUSHI_API_ENDPOINT is only
for self-hosting.
The runner signs in in a fresh headless Chromium, picks the session cookie
set for your app’s domain, and saves it with
PATCH /v1/admin/inventory/:projectId/settings. The crawler and synthetic
monitor read it from there on every run.
In CI
Cookies expire. Rebake them on a schedule (e.g. nightly) so the synthetic monitor never falls back to an unauthenticated walk:
name: Mushi auth bootstrap
on:
schedule:
- cron: '0 6 * * *'
workflow_dispatch:
jobs:
refresh:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
# The runner launches Chromium; a fresh runner has no Playwright browser.
- run: npx --yes -p @mushi-mushi/inventory-auth-runner playwright install --with-deps chromium
- uses: kensaurus/mushi-mushi/packages/mcp-ci@master
with:
api-key: ${{ secrets.MUSHI_API_KEY }}
project-id: ${{ secrets.MUSHI_PROJECT_ID }}
command: auth-bootstrap
env:
TEST_USER_EMAIL: ${{ secrets.MUSHI_TEST_USER_EMAIL }}
TEST_USER_PASSWORD: ${{ secrets.MUSHI_TEST_USER_PASSWORD }}The auth-bootstrap command in @mushi-mushi/mcp-ci
is a convenience wrapper that calls this runner (with MUSHI_PROJECT set
from project-id); use it from CI. It does not install a browser itself.