Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions docs/marketing/devrel/demos/org-scoped-api-keys-demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Org-Scoped API Keys: Enterprise Key Management for Multi-Agent Teams

**Published:** April 20, 2026 | **Author:** Molecule AI Marketing

---

When your engineering team scales from two agents to twenty, the last thing you want is a single `ADMIN_TOKEN` hardcoded in your environment. It's a single point of failure, impossible to rotate without downtime, and impossible to audit. Today's launch changes that.

We're rolling out **org-scoped API keys** — named, revocable, audit-trail-enabled tokens that live at the organization level and can reach any workspace in your org without breaking the security model.

## What Are Org-Scoped API Keys?

Org-scoped API keys are long-lived credentials minted at the organization level via the Canvas UI or the `POST /org/tokens` endpoint. Each key has:

- A **display name** you choose at creation time (e.g., `ci-deploy-bot`, `devops-rev-proxy`)
- A **sha256 hash** stored server-side — the plaintext is shown once and never again
- A **prefix** (first 8 characters) visible in listings so you can identify keys without exposing secrets
- A **created-by** field that tracks provenance in the audit trail
- **Immediate revocation** — drop a key and it stops being accepted on the very next request

The keys work across all workspaces in your org — not just admin-surface endpoints, but also per-workspace sub-routes like `/workspaces/:id/channels` and `/workspaces/:id/tokens`.

## Why Enterprise Teams Need Org-Level Key Management

### The `ADMIN_TOKEN` problem

A single env-var token works for prototypes. For production multi-agent systems it creates three compounding risks:

1. **Rotation requires downtime.** You can't rotate a token used by ten agents simultaneously. You rotate, or you don't — and both choices are bad.
2. **No attribution.** When something calls your API, you have no idea which agent or integration is responsible.
3. **No compartmentalization.** One compromised token compromises everything.

### What org-scoped keys give you

| Capability | `ADMIN_TOKEN` | Org-Scoped Keys |
|---|---|---|
| Rotate without downtime | ❌ | ✅ (one key revokes, another takes over) |
| Identify caller per request | ❌ | ✅ (audit prefix in every log line) |
| Revoke a single integration | ❌ | ✅ (per-key revocation) |
| Assign to workspace subroutes | ❌ | ✅ |
| Audit trail with attribution | Partial | ✅ (`created_by` + prefix in logs) |

## Audit Trail and Rate-Limit Controls

Every request authenticated with an org API key carries the key's prefix in the audit log, making it straightforward to trace calls back to a specific integration. When combined with the `created_by` field stored at mint time, you get full provenance: *which admin created this key, when, and what it's been calling.*

Rate-limit controls for org tokens are planned as a near-term follow-on (see roadmap, P3). For now, the token hierarchy is:

- **Lazy bootstrap** (Tier 0) — only active when there are zero org tokens and no `ADMIN_TOKEN` at all
- **WorkOS session** (Tier 1) — verified user sessions
- **Org API tokens** (Tier 2a) — new org-scoped keys (primary path for service integrations)
- **`ADMIN_TOKEN` env var** (Tier 2b) — break-glass for operators, CLI tooling
- **Workspace tokens** (Tier 3) — deprecated per-workspace tokens

## How to Get Started

### Mint a key via API

```bash
curl -X POST https://your-deployment.molecule.ai/org/tokens \
-H "Authorization: Bearer <your-admin-session-token>" \
-H "Content-Type: application/json" \
-d '{
"name": "ci-deploy-bot",
"description": "GitHub Actions deploy pipeline"
}'
```

Response (plaintext shown once — store it securely):

```json
{
"id": "tok_01HXYZ...",
"name": "ci-deploy-bot",
"display_prefix": "mole_a1b2",
"created_at": "2026-04-20T14:00:00Z",
"created_by": "admin@example.com"
}
```

### List and revoke keys

```bash
# List all active keys (prefix-only, no plaintext)
curl https://your-deployment.molecule.ai/org/tokens \
-H "Authorization: Bearer <your-admin-session-token>"

# Revoke a key immediately
curl -X DELETE https://your-deployment.molecule.ai/org/tokens/tok_01HXYZ... \
-H "Authorization: Bearer <your-admin-session-token>"
```

### Use in a workspace sub-route

```bash
# Token hits workspace sub-route via org auth
curl https://your-deployment.molecule.ai/workspaces/ws_abc123/channels \
-H "Authorization: Bearer mole_a1b2c3d4..."
```

## Competitive Note: Hermes v0.10.0 Tool Gateway

Hermes v0.10.0 ships bundled tool primitives (web search, image generation, TTS, browser automation) as platform-level features for paid Portal subscribers. This positions Hermes as "batteries included" for single-user AI. However, Hermes has no multi-agent or A2A support — its tool gateway operates in a single-user context.

Molecule's org-scoped API keys reinforce a different value proposition: **enterprise-grade identity and access management for multi-agent teams.** The skills architecture offers greater composability than Hermes' bundled approach, and org tokens now give teams the access-control primitives needed to deploy that composability safely in production.

Hermes' bundled tools are a valid competitive concern at the feature-surface level. Org-scoped API keys address a deeper need — the same teams comparing bundled-vs-skills architectures need first-class auth and audit before they're comfortable shipping to production. This launch moves Molecule closer to that confidence threshold.

---

## TTS Announcement Clip (45 seconds)

*[Suggested script for TTS / social audio: read at ~150 words/min]*

> **Clip script:**
>
> "Molecule AI is shipping org-scoped API keys — enterprise-grade credentials for multi-agent teams. Mint named, revocable tokens from the Canvas UI or REST API. No more single ADMIN_TOKEN across your whole deployment. Each key gets a display prefix for audit attribution, a created-by trace, and immediate revocation. Tokens work across every workspace in your org — including sub-routes, not just admin endpoints. Rotate keys without downtime. Identify which integration called what, every time. Get started in under five minutes: POST to slash-org-slash-tokens, store the plaintext once, and you're live. Org-scoped API keys are available now on all production deployments. Head to the docs or open Canvas to mint your first key."

---

*Attach comments to issue #1114 for review. Labels: `area:content-marketer`, `marketing`, `ready-for-review`.*
194 changes: 194 additions & 0 deletions org-api-keys/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# Org-Scoped API Keys — Working Demo

> **PR:** #1105 — `feat(auth): org-scoped API keys`
> **What it ships:** `workspace-server/internal/handlers/org_tokens.go` — named, revocable org-admin tokens minted from canvas UI or CLI
> **Acceptance criteria:** working demo + repo link + 1-min screencast or README walkthrough

---

## What This Demo Shows

An org admin can mint a named, revocable API key from the CLI (or canvas). The key is a full-admin bearer token for the tenant platform — it authorizes every admin-gated endpoint on the tenant (all workspaces, org settings, bundles, secrets). The demo shows minting, using, and revoking the key.

**Key facts:**
- 256-bit entropy, base64url encoded. Prefix shown in UI for identification.
- Plaintext returned exactly once at mint time — never stored.
- `org-token:<prefix>` format in audit logs and API responses.
- Revocation is immediate and idempotent.

**Routes:**
| Method | Path | What |
|---|---|---|
| `GET` | `/org/tokens` | List live (non-revoked) tokens |
| `POST` | `/org/tokens` | Mint a new token — plaintext returned once |
| `DELETE` | `/org/tokens/:id` | Revoke a token |

---

## Prerequisites

- Molecule AI platform running (`go run ./cmd/server` from `workspace-server/`)
- Canvas open at `http://localhost:3000`
- Admin session cookie OR an existing org-scoped token
- `curl` and `jq` on the caller machine

---

## Working Demo Script

### 1. Mint a named org token

```bash
PLATFORM="http://localhost:8080"
COOKIE="session=$(curl -s -c - -X POST "$PLATFORM/cp/auth/login" \
-d 'email=admin@example.com&password=...' | grep session | awk '{print $7}')"

# Mint a named org token
curl -s -X POST "$PLATFORM/org/tokens" \
-H "Cookie: $COOKIE" \
-H "Content-Type: application/json" \
-d '{"name": "ci-pipeline-key"}' | jq
```

Response (200):
```json
{
"id": "otok_xxxxxxxxxxxx",
"prefix": "mL9kXp2W",
"name": "ci-pipeline-key",
"auth_token": "org-token:mL9kXp2WQrZvT8sBmN3cD4eF6gH0iJ1kL9pM3nO5qR7tU0vW1xY2zA3bC4dE5fG",
"warning": "copy this token now; it will not be shown again"
}
```

**Save the `auth_token` value — it cannot be retrieved again.**

---

### 2. Use the org token to list workspaces

The token is a full-admin bearer. Pass it in the `Authorization` header:

```bash
ORG_TOKEN="org-token:mL9kXp2WQrZvT8sBmN3cD4eF6gH0iJ1kL9pM3nO5qR7tU0vW1xY2zA3bC4dE5fG"

curl -s "$PLATFORM/org/tokens" \
-H "Authorization: Bearer $ORG_TOKEN" | jq
```

Response — lists all live org tokens:
```json
{
"tokens": [
{
"id": "otok_xxxxxxxxxxxx",
"prefix": "mL9kXp2W",
"name": "ci-pipeline-key",
"created_by": "admin@example.com",
"created_at": "2026-04-21T00:00:00Z",
"revoked_at": null
}
],
"count": 1
}
```

Use the token to call any admin-gated endpoint:

```bash
# List all workspaces in the org
curl -s "$PLATFORM/workspaces" \
-H "Authorization: Bearer $ORG_TOKEN" | jq '.workspaces[].id'

# List all org bundles
curl -s "$PLATFORM/bundles" \
-H "Authorization: Bearer $ORG_TOKEN" | jq '.'

# Read workspace secrets
curl -s "$PLATFORM/workspaces/ws-123/secrets/values" \
-H "Authorization: Bearer $ORG_TOKEN" | jq
```

---

### 3. Revoke the token and confirm 401

```bash
# Revoke via DELETE
curl -s -X DELETE "$PLATFORM/org/tokens/otok_xxxxxxxxxxxx" \
-H "Authorization: Bearer $ORG_TOKEN" \
-H "Content-Type: application/json" \
-w "\nHTTP %{http_code}\n"
```

Response:
```
HTTP 200
```

Revocation is immediate. Confirm the token no longer works:

```bash
curl -s "$PLATFORM/org/tokens" \
-H "Authorization: Bearer $ORG_TOKEN" \
-w "\nHTTP %{http_code}\n"
```

Response:
```
HTTP 401
{"error":"invalid or revoked org api token"}
```

The token is dead. Revocation is permanent — the row is soft-deleted (revoked_at timestamp set). The same plaintext can never authenticate again.

---

### 4. Verify the token shows as revoked in the list

Revoke requires the session cookie (not the org token — org tokens can't revoke other org tokens):

```bash
curl -s "$PLATFORM/org/tokens" \
-H "Cookie: $COOKIE" | jq '.tokens[0].revoked_at'
```

Response:
```json
"2026-04-21T00:05:00Z"
```

Audit trail: `created_by` on the original mint + `revoked_at` timestamp provide full provenance tracking.

---

## Screencast Outline (1 min)

**0:00–0:10** Terminal: mint a named org token via `POST /org/tokens`. Response shows `auth_token` field — highlight the "copy now" warning.

**0:10–0:25** Terminal: use the token to call `GET /workspaces`. Output shows workspace IDs. Call out `Authorization: Bearer org-token:...` header.

**0:25–0:40** Terminal: revoke the token via `DELETE /org/tokens/:id`. Output: `HTTP 200`. Immediately try to call `/org/tokens` again — `HTTP 401` shown in terminal.

**0:40–0:55** Canvas: switch to Org Settings → API Keys tab. The revoked token shows `revoked_at` timestamp. New token listed alongside any others.

**0:55–1:00** Narration: *"Org-scoped API keys: mint named tokens, use them anywhere, revoke them instantly. Full admin access, one line of curl. No session cookies, no browser. org-token keys, from Molecule AI."*

---

## TTS Narration Script (30s)

> Org-scoped API keys let you mint a full-admin bearer token for the Molecule AI platform — named, revocable, auditable. Mint one from the CLI or canvas, use it to call any admin endpoint, revoke it when you're done. The token is 256 bits of entropy, shown exactly once at mint time, and the revoke is immediate. No session cookies, no browser. Just a bearer token that works until you revoke it. Org API keys, from Molecule AI.

---

## Code Reference

| File | What |
|---|---|
| `workspace-server/internal/handlers/org_tokens.go` | OrgTokenHandler: List, Create, Revoke |
| `workspace-server/internal/orgtoken/tokens.go` | `Issue()`, `Revoke()`, `List()` — token lifecycle |
| `workspace-server/migrations/035_org_api_tokens.up.sql` | Schema: `org_api_tokens` table |
| `canvas/src/components/settings/OrgTokensTab.tsx` | Canvas UI: org token management tab |

**Source:** `workspace-server/internal/handlers/org_tokens.go` (PR #1105)
Binary file added org-api-keys/narration.mp3
Binary file not shown.
Loading