Docs / api / authentication

Authentication

API key authentication for Runra Sandbox — obtaining keys, Bearer token headers, scopes, key rotation, and security best practices

All Runra Sandbox API requests require authentication using a Bearer token in the Authorization header. This page covers how to obtain, configure, and secure your API keys.

Obtaining an API Key

Via the Dashboard

  1. Log in to the Runra Dashboard.
  2. Navigate to Settings → API Keys.
  3. Click Create API Key.
  4. Give your key a descriptive name (e.g., production-ci, local-dev).
  5. Select the appropriate scopes (see Scopes & Permissions).
  6. Copy the generated key immediately — it will not be shown again.

Via the CLI

runra auth login
runra auth create-key --name "production-ci" --scope "full"

Key Format

API keys are opaque tokens prefixed with rra_:

rra_live_x7k2m9p4q1w3v5b8n6c0d2a4f

Never commit API keys to source control. Use environment variables:

export RUNRA_API_KEY="rra_live_x7k2m9p4q1w3v5b8n6c0d2a4f"

Authenticating Requests

Include the key in the Authorization header on every request:

curl https://api.box.runra.dev/v1/sandboxes \
  -H "Authorization: Bearer $RUNRA_API_KEY"

TypeScript SDK

The SDK reads RUNRA_API_KEY from the environment automatically:

import { Runra } from "@runra/sandbox";

const client = new Runra({
  apiKey: process.env.RUNRA_API_KEY, // or auto-reads from env
});

// Or pass explicitly
const client = new Runra({
  apiKey: "rra_live_x7k2m9p4q1w3v5b8n6c0d2a4f",
});

Python SDK

from runra import Runra

client = Runra(api_key="rra_live_x7k2m9p4q1w3v5b8n6c0d2a4f")

Scopes and Permissions

API keys can be scoped to limit what operations they can perform:

ScopeDescription
sandbox:createCreate new sandboxes
sandbox:readList and get sandbox details
sandbox:deleteTerminate sandboxes
sandbox:pausePause and resume sandboxes
sandbox:executeRun code inside sandboxes
sandbox:filesRead and write files
sandbox:portsExpose and close ports
sandbox:*Full sandbox management
billing:readView usage and billing
billing:manageUpdate billing details
webhooks:manageCreate and manage webhooks

Predefined profiles:

ProfileIncludes
read-onlysandbox:read, billing:read
sandbox-usersandbox:create, sandbox:read, sandbox:delete, sandbox:pause, sandbox:execute, sandbox:files, sandbox:ports
adminsandbox:*, billing:*, webhooks:manage

Create a scoped key:

runra auth create-key \
  --name "ci-worker" \
  --scope "sandbox:create,sandbox:execute,sandbox:delete"

Key Rotation

Rotate API keys regularly to limit exposure from leaked credentials. Runra supports overlapping keys during rotation:

Rotation Steps

  1. Create a new key with the same scopes:
runra auth create-key --name "production-v2" --scope "admin"
# → rra_live_newkey...
  1. Deploy the new key to all services. Both keys are valid simultaneously.

  2. Revoke the old key after confirming the new key works:

runra auth revoke-key --key-id "key_abc123def456"

Via the Dashboard

  1. Go to Settings → API Keys.
  2. Click Rotate on the key you want to replace.
  3. A new key is created and the old key remains valid for 7 days.
  4. After 7 days, the old key is automatically revoked.

Automated Rotation

For production systems, use the key listing endpoint to check key ages:

curl https://api.box.runra.dev/v1/keys \
  -H "Authorization: Bearer $RUNRA_API_KEY"
{
  "data": [
    {
      "id": "key_abc123def456",
      "name": "production-v1",
      "prefix": "rra_live_x7",
      "createdAt": "2025-12-15T10:00:00Z",
      "lastUsedAt": "2026-06-15T09:55:00Z",
      "scopes": ["sandbox:*"],
      "isActive": true
    }
  ]
}

Security Best Practices

Never expose keys in client-side code

API keys grant access to create and manage sandboxes. Only use them in server-side or edge environments:

// ✅ Server-side (Next.js API route, Express, worker)
const runra = new Runra({ apiKey: process.env.RUNRA_API_KEY });

// ❌ Client-side (browser, mobile app)
// const runra = new Runra({ apiKey: "rra_live_..." });

If you need browser access, proxy requests through your backend.

Use environment variables

# .env (never commit this file)
RUNRA_API_KEY=rra_live_x7k2m9p4q1w3v5b8n6c0d2a4f
// Load from env
const apiKey = process.env.RUNRA_API_KEY;
if (!apiKey) {
  throw new Error("RUNRA_API_KEY is required");
}

Scope keys to minimum permissions

Give each integration only the scopes it actually needs:

# CI pipeline only needs to create, execute, and clean up
runra auth create-key \
  --name "ci-pipeline" \
  --scope "sandbox:create,sandbox:execute,sandbox:delete"

Monitor key usage

Check the API keys dashboard for unusual activity. Keys show lastUsedAt timestamps and request counts. Set up alerts for:

  • Keys not used in 30+ days (revoke them)
  • Unexpected scope usage
  • Sudden spikes in request volume

Revoke compromised keys immediately

# Via CLI
runra auth revoke-key --key-id "key_abc123def456"

# Via API
curl -X DELETE https://api.box.runra.dev/v1/keys/key_abc123def456 \
  -H "Authorization: Bearer $RUNRA_API_KEY"

Authentication Errors

StatusCodeMeaning
401UNAUTHORIZEDMissing Authorization header or invalid key
403FORBIDDENValid key but insufficient scope for the operation
401KEY_EXPIREDKey has been revoked or expired
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid API key",
    "requestId": "req_a1b2c3d4"
  }
}

Next Steps