Skip to main content
Mesa has two kinds of credentials that can be used for programmatic access:
  1. API keys: long-lived credentials meant for use in trusted environments (ex. your application server).
  2. Ephemeral tokens (JWTs): short-lived access tokens meant for use in ephemeral, less-trusted environments (ex. an agent sandbox).
API keys with admin scope can be used to mint both API keys and ephemeral tokens, but ephemeral tokens cannot be used to mint more credentials. Keep API keys in trusted infrastructure. Use ephemeral tokens anywhere you would be uncomfortable leaving a durable secret behind: agent sandboxes, disposable VMs, container sessions, or per-user agent jobs.

Basic Usage

The recommended pattern depends on how you mount MesaFS:
  • For app mounts, construct the SDK client with an API key in your trusted backend. When you call mesa.fs.mount(...), the SDK signs a scoped JWT under the hood and uses it for that mount.
  • For POSIX mounts, mint a scoped, ephemeral token in your trusted backend, pass it into the sandbox as MESA_API_KEY, then run mesa mount inside the sandbox.
import { Mesa } from "@mesadev/sdk";

// Runs in your trusted backend with a durable API key.
const mesa = new Mesa({
  apiKey: process.env.MESA_API_KEY,
  org: "my-org",
});

// Mint a short-lived token for the sandbox.
const { token } = await mesa.tokens.create({
  scopes: ["read", "write"],
  repos: ["my-org/agent-workspace"],
  ttl_seconds: 60 * 60,
});

// Set up your preferred sandbox...

// Pass only the token into the less-trusted environment as MESA_API_KEY.
await sandbox.commands.run("mesa mount --daemonize", {
  env: {
    MESA_ORG: "my-org",
    MESA_API_KEY: token,
  },
});
Tokens are used for the lifetime of the mount. They default to a 1 hour TTL, have a maximum TTL of 24 hours, and are not refreshed automatically. Choose a ttl that covers the mount’s work.

REST and Git APIs

The REST API and Git server both accept a bearer credential, which can be either a durable API key or ephemeral JWT.

REST API

Include the credential in the Authorization header:
curl -H "Authorization: Bearer $MESA_API_KEY" \
  https://api.mesa.dev/v1/my-org/repos

Git API

Use the credential as the password when cloning or pushing:
git clone https://t:$MESA_API_KEY@api.mesa.dev/my-org/my-repo.git

Minting Credentials

Ephemeral Tokens

Use mesa.tokens.create(...) when you need to hand a credential to another environment, such as a sandbox where the Mesa CLI will run.
import { Mesa } from "@mesadev/sdk";

const mesa = new Mesa({
  apiKey: process.env.MESA_API_KEY,
  org: "my-org",
});

const { token, expires_at } = await mesa.tokens.create({
  scopes: ["read", "write"],
  repos: ["my-org/agent-workspace"],
  ttl_seconds: 60 * 60, // 1 hour; max 86400
});

console.log(expires_at);
The scopes of the minted token are clamped to the permissions of the API key used to initialize the SDK client. Ephemeral tokens cannot be individually revoked or refreshed. They expire on their own. To end access early, revoke the signing API key.

API Keys

API keys are long-lived bearer credentials. Use them for trusted services that need to create repos, manage API keys, mint tokens, or construct SDK clients. Your first API key is created in the Mesa dashboard. If you haven’t done this yet, follow the Quickstart to create the initial key. Construct SDK clients with an API key:
import { Mesa } from "@mesadev/sdk";

const mesa = new Mesa({
  apiKey: process.env.MESA_API_KEY,
  org: "my-org",
});
Create additional API keys through the dashboard, SDK, or REST API:
const key = await mesa.apiKeys.create({
  org: "my-org",
  name: "Production backend",
  scopes: ["admin"],
});

// Store this securely. The full key is only shown once.
console.log(key.key);
Create narrower keys where possible:
await mesa.apiKeys.create({
  org: "my-org",
  name: "Read-only analytics",
  scopes: ["read"],
});

await mesa.apiKeys.create({
  org: "my-org",
  name: "CI",
  scopes: ["read", "write"],
  expires_in_seconds: 60 * 60 * 24 * 90,
});
API keys may be created with expires_in_seconds, or without an expiration. Revoking an API key immediately invalidates the key and every ephemeral token signed from it.
await mesa.apiKeys.revoke({
  org: "my-org",
  id: "key_abc123",
});

Scopes

Scopes are hierarchical. Each level includes the permissions from the levels below it.
ScopeDescription
readClone, fetch, and view repositories, bookmarks, changes, commits, diffs, and content
writeEverything read can do, plus push, create/update/delete repos, and create/move/delete bookmarks and changes
adminEverything write can do, plus API key and webhook management
API keys/JWTs can be org-wide or restricted to specific repositories. Use repo-scoped credentials when a service only needs access to a subset of repos. An ephemeral token cannot exceed the scopes of the API used when minting the token.

Common Failures

SymptomLikely cause
UNAUTHORIZEDThe API key or token is missing, malformed, expired, or revoked
FORBIDDENThe credential is valid but lacks the required scope or repository access
Mount starts but later fails with auth errorsThe mount’s credential expired; re-mint a token and remount
Sandbox can access too many reposThe token was not repo-scoped; mint it with repos: ["org/repo"]