Configuration

Configuration is optional. All services start with sensible defaults. To customize seed data, create emulate.config.yaml in your project root (or pass --seed):

tokens:
  gho_test_token_admin:
    login: admin
    scopes:
      - repo
      - user
      - admin:org
      - admin:repo_hook
  gho_test_token_user1:
    login: octocat
    scopes:
      - repo
      - user

Vercel Seed Config

vercel:
  users:
    - username: developer
      name: Developer
      email: dev@example.com
  teams:
    - slug: my-team
      name: My Team
  projects:
    - name: my-app
      team: my-team
      framework: nextjs
      envVars:
        - key: DATABASE_URL
          value: postgres://localhost
          target: [production, preview]

Vercel Integrations

Register Vercel OAuth integrations for strict client validation:

vercel:
  integrations:
    - client_id: "oac_abc123"
      client_secret: "secret_abc123"
      name: "My Vercel App"
      redirect_uris:
        - "http://localhost:3000/api/auth/callback/vercel"

GitHub Seed Config

github:
  users:
    - login: octocat
      name: The Octocat
      email: octocat@github.com
      bio: I am the Octocat
      company: GitHub
      location: San Francisco

  orgs:
    - login: my-org
      name: My Organization
      description: A test organization

  repos:
    - owner: octocat
      name: hello-world
      description: My first repository
      language: JavaScript
      topics: [hello, world]
      auto_init: true
    - owner: my-org
      name: org-repo
      description: An organization repository
      language: TypeScript
      auto_init: true

GitHub OAuth Apps

Register OAuth applications so the emulator validates client_id, client_secret, and redirect_uri during the OAuth flow:

github:
  oauth_apps:
    - client_id: "Iv1.abc123"
      client_secret: "secret_abc123"
      name: "My Web App"
      redirect_uris:
        - "http://localhost:3000/api/auth/callback/github"

If no oauth_apps are configured, the emulator accepts any client_id (backward-compatible). With apps configured, strict validation is enforced.

GitHub Apps

Full GitHub App support with JWT authentication and installation access tokens:

github:
  apps:
    - app_id: 12345
      slug: "my-github-app"
      name: "My GitHub App"
      private_key: |
        -----BEGIN RSA PRIVATE KEY-----
        ...your PEM key...
        -----END RSA PRIVATE KEY-----
      permissions:
        contents: read
        issues: write
      events: [push, pull_request]
      installations:
        - installation_id: 100
          account: my-org
          repository_selection: all
          permissions:
            contents: read

Endpoints:

  • GET /app - get authenticated app (JWT required)
  • GET /app/installations - list app installations
  • GET /app/installations/:id - get installation
  • POST /app/installations/:id/access_tokens - create installation access token
  • GET /repos/:owner/:repo/installation - find repo installation
  • GET /orgs/:org/installation - find org installation
  • GET /users/:username/installation - find user installation

JWT authentication: sign a JWT with { iss: "<app_id>" } using the app's private key (RS256). The emulator verifies the signature and resolves the app.

Google Seed Config

google:
  users:
    - email: testuser@example.com
      name: Test User
    - email: admin@acme.com
      name: Admin
      hd: acme.com
  oauth_clients:
    - client_id: my-client-id.apps.googleusercontent.com
      client_secret: GOCSPX-secret
      redirect_uris:
        - http://localhost:3000/api/auth/callback/google
  labels:
    - id: Label_ops
      user_email: testuser@example.com
      name: Ops/Review
  messages:
    - id: msg_welcome
      user_email: testuser@example.com
      from: welcome@example.com
      to: testuser@example.com
      subject: Welcome to the Gmail emulator
      body_text: You can now test Gmail, Calendar, and Drive flows locally.
      label_ids: [INBOX, UNREAD]
  calendars:
    - id: primary
      user_email: testuser@example.com
      summary: testuser@example.com
      primary: true
  calendar_events:
    - id: evt_kickoff
      user_email: testuser@example.com
      calendar_id: primary
      summary: Project Kickoff
      start_date_time: 2025-01-10T09:00:00.000Z
      end_date_time: 2025-01-10T09:30:00.000Z
  drive_items:
    - id: drv_docs
      user_email: testuser@example.com
      name: Docs
      mime_type: application/vnd.google-apps.folder
      parent_ids: [root]

Hosted domain (hd) claim

Google Workspace accounts include an hd claim in ID tokens and userinfo responses identifying the user's hosted domain. The emulator derives this automatically from the user's email domain. Consumer domains (gmail.com, googlemail.com) omit the claim, matching real Google behavior.

To override the derived value, set hd on a seeded user. To suppress the claim entirely, set hd to an empty string.

Slack Seed Config

slack:
  team:
    name: My Workspace
    domain: my-workspace
  users:
    - name: developer
      real_name: Developer
      email: dev@example.com
      is_admin: true
  channels:
    - name: general
      topic: General discussion
    - name: engineering
      topic: Engineering discussions
      is_private: true
  bots:
    - name: my-bot
  oauth_apps:
    - client_id: "12345.67890"
      client_secret: example_client_secret
      name: My Slack App
      redirect_uris:
        - http://localhost:3000/api/auth/callback/slack
  incoming_webhooks:
    - channel: general
      label: CI Notifications
  signing_secret: my_signing_secret

When no OAuth apps are configured, the emulator accepts any client_id. With apps configured, strict validation is enforced.

Apple Seed Config

apple:
  users:
    - email: testuser@icloud.com
      name: Test User
      given_name: Test
      family_name: User
    - email: private@example.com
      name: Private User
      is_private_email: true
  oauth_clients:
    - client_id: com.example.app
      team_id: TEAM001
      name: My Apple App
      redirect_uris:
        - http://localhost:3000/api/auth/callback/apple

Users with is_private_email: true get a generated @privaterelay.appleid.com email in the id_token.

Microsoft Seed Config

microsoft:
  users:
    - email: testuser@outlook.com
      name: Test User
      given_name: Test
      family_name: User
      tenant_id: 9188040d-6c67-4c5b-b112-36a304b66dad
  oauth_clients:
    - client_id: example-client-id
      client_secret: example-client-secret
      name: My Microsoft App
      redirect_uris:
        - http://localhost:3000/api/auth/callback/microsoft-entra-id
      tenant_id: 9188040d-6c67-4c5b-b112-36a304b66dad

AWS Seed Config

aws:
  region: us-east-1
  s3:
    buckets:
      - name: my-app-bucket
      - name: my-app-uploads
        region: eu-west-1
  sqs:
    queues:
      - name: my-app-events
      - name: my-app-dlq
        visibility_timeout: 60
      - name: my-app-orders.fifo
        fifo: true
  iam:
    users:
      - user_name: developer
        create_access_key: true
    roles:
      - role_name: lambda-execution-role
        description: Role for Lambda function execution

Default seed (always created): S3 bucket emulate-default, SQS queue emulate-default-queue, IAM user admin with access key pair.

Okta Seed Config

okta:
  users:
    - login: testuser@example.com
      email: testuser@example.com
      firstName: Test
      lastName: User
  groups:
    - name: Everyone
      description: All users
  apps:
    - name: My App
      label: My App
  authorization_servers:
    - name: default
      audiences: ["api://default"]

MongoDB Atlas Seed Config

mongoatlas:
  projects:
    - name: my-project
  clusters:
    - project: my-project
      name: my-cluster
  database_users:
    - project: my-project
      username: app-user

Resend Seed Config

resend:
  domains:
    - name: example.com
  api_keys:
    - name: default

Stripe Seed Config

stripe:
  customers:
    - name: Test Customer
      email: test@example.com
  products:
    - name: Pro Plan
  prices:
    - product: Pro Plan
      unit_amount: 2000
      currency: usd
      recurring:
        interval: month