Beam Plugin: Publish Redacted Coding Sessions to OpenClaw Catalog

Learn how to enable and configure the Beam plugin to publish cleaned coding-session snapshots into a shared read-only catalog. This guide is for OpenClaw administrators who need to share session data securely.

Read this when

  • Sharing a Claude Code or Codex session with trusted Gateway operators
  • Continuing a beamed conversation with a Team agent
  • Configuring an authenticated session-ingest endpoint without connecting a node
  • Auditing what Beam stores and exposes

The beam plugin that ships with OpenClaw takes a cleaned coding-session snapshot delivered through authenticated HTTP and shows it in the existing external-session catalog of the Control UI. The originating machine only pushes text outward; OpenClaw never establishes a connection back to that computer and gains no filesystem, terminal, tool, or node access.

Although Beam comes bundled with OpenClaw, it starts out turned off. Activating it brings up:

  • POST /api/v1/beam/sessions
  • the read-only Beam session catalog located in the Control UI sidebar

Enable

openclaw plugins enable beam
openclaw gateway restart

The same settings expressed differently:

{
  plugins: {
    entries: {
      beam: { enabled: true },
    },
  },
}

When the ingest route is unnecessary, turn the plugin off:

openclaw plugins disable beam
openclaw gateway restart

Authentication

Standard Gateway HTTP authentication guards the receiver. This is not an open endpoint for anonymous submissions.

  • When gateway.auth.mode: "trusted-proxy" is in play, route requests through the identity-aware proxy you have configured. Beam depends on Gateway authentication, yet it does not store proxy identity headers as uploader attribution.
  • For token or password authentication, transmit Authorization: Bearer <gateway-token-or-password>.
  • Avoid enabling Beam with gateway.auth.mode: "none" unless a separate private ingress authenticates every request completely.

A deployment protected by Cloudflare Access can authenticate a local CLI without ever exposing a GitHub token:

cloudflared access login https://gateway.example.com
cloudflared access curl https://gateway.example.com/api/v1/beam/sessions \
  -H 'Content-Type: application/json' \
  --data-binary @sanitized-beam.json

Within openclaw/agent-skills, the beam skill manages local transcript discovery, redaction, Cloudflare Access login, and upload for Claude Code and Codex.

Request

POST /api/v1/beam/sessions
Content-Type: application/json
{
  "version": 1,
  "beamId": "0123456789abcdef0123456789abcdef",
  "source": "claude",
  "title": "Fix the upload flow",
  "updatedAt": "2026-07-20T12:00:00.000Z",
  "completed": false,
  "items": [
    { "type": "userMessage", "text": "Fix the upload flow." },
    { "type": "agentMessage", "text": "Implemented and tested." },
    { "type": "other", "text": "3 read, 2 write, 1 execute; raw tool outputs dropped: 4" }
  ]
}

The schema remains closed. Beam rejects unknown fields, invalid item types, empty text, more than 200 items, item text exceeding 6,000 characters, non-JSON requests, and bodies larger than 56 KiB.

A successful upload returns the stable Beam id plus a relative Control UI URL:

{
  "ok": true,
  "beamId": "0123456789abcdef0123456789abcdef",
  "url": "/chat/main?catalog=beam&host=gateway&thread=<beamId>"
}

Re-uploading the same beamId refreshes the existing catalog row. Once a completed upload lands, the row status becomes completed; earlier updates show as live.

Storage and visibility

Sanitized payloads live in OpenClaw's shared SQLite-backed plugin state, with these limits:

  • a cap of 500 sessions
  • seven-day retention that each update resets
  • oldest-entry eviction once the catalog hits its ceiling
  • server receipt time decides catalog ordering; clients cannot push themselves forward with a fabricated timestamp

The catalog is deliberately shared across the Gateway operator domain. Anyone holding operator.read can view every beamed session, but uploads demand operator.write or operator.admin. Uploader identity is never kept, and any write-authorized operator who knows a Beam id can modify that row. OpenClaw operator scopes do not act as tenant isolation; run a separate Gateway when sessions must stay isolated across teams or machines.

Security boundary

Beam publishes sessions passively; it is not a remote-control mechanism.

  • It carries no continueSession, archive, terminal, tool, or node capability.
  • It accepts only text-only normalized transcript items, never HTML, scripts, archives, attachments, or server-fetched URLs.
  • The official skill strips raw tool results, reasoning, prompts, local paths, credentials, cookies, and auth material prior to upload.
  • The receiver still handles every transcript as untrusted text. Moving a beamed transcript into a fresh agent session is a separate operator action.
  • Rate limits and concurrency limits apply before the body is read.

Mirroring

Beam can also serve as the sender: an opt-in mirror that continuously publishes this machine's active local coding sessions (Claude Code, Codex, and other registered session catalogs) to a remote Beam receiver, like a shared team Gateway. Teammates then watch near-live session transcripts in the remote Control UI without any access to the source machine.

{
  plugins: {
    entries: {
      beam: {
        enabled: true,
        config: {
          mirror: {
            endpoint: "https://team.example.com/api/v1/beam/sessions",
            token: { source: "env", provider: "default", id: "BEAM_TEAM_TOKEN" },
            catalogs: ["claude", "codex"],
          },
        },
      },
    },
  },
}
  • endpoint (required): the final remote receiver URL. Redirect responses (301, 302, 303, 307, and 308) are not followed; point the destination URL directly. After a redirect, repeated polls are suppressed for the current mirror service instance. A Gateway restart probes the configured endpoint once more so a receiver corrected at the same URL can recover. HTTPS is enforced for non-loopback hosts; plaintext http:// is accepted only for localhost/127.0.0.1/::1 development.
  • token: Gateway credential for the remote receiver, sent as Authorization: Bearer. Accepts a plain string or a secret reference; a configured-but-unresolved token pauses mirroring instead of sending unauthenticated requests. Deployments fronted by an identity-aware proxy need an ingress that accepts this bearer credential.
  • catalogs (required): the session catalog ids to mirror, as explicit per-catalog consent; an omitted or empty list mirrors nothing. The local beam receiver catalog is always excluded so two mirrored Gateways cannot re-mirror each other's rows.
  • pollSeconds (default 30, minimum 10): how often the mirror scans local catalogs.
  • activeWindowMinutes (default 180): sessions with newer activity than this window count as live and stay mirrored; when a session goes idle past the window the mirror sends one final completed update.

The mirror applies the same redaction contract as the beam skill before anything leaves the machine: only user and agent message text is uploaded, while reasoning, tool calls, tool results, and raw payloads are replaced with compact counts. Snapshots are capped to the receiver limits (200 items, 56 KiB), dropping oldest entries first and marking the upload truncated. Sessions on paired nodes are not mirrored; the mirror shares only sessions from this Gateway's machine, newest 32 first.

Troubleshooting

404 Not Found

: The Beam plugin is disabled, the Gateway has not restarted since enablement, or the request is reaching another Gateway.

401 Unauthorized

: The request did not satisfy Gateway HTTP auth. Check the bearer credential or trusted-proxy/Access session.

405 Method Not Allowed

: The receiver accepts only POST.

413 Payload Too Large

: The serialized request exceeded 56 KiB. The official skill drops older sanitized messages until the snapshot fits.

429 Too Many Requests

: The authenticated client exceeded the bounded request or concurrency limit. Retry after the current minute window.

beam mirror upload blocked ... receiver returned redirect

: The configured mirror endpoint returned a redirect. Beam does not follow redirects and suppresses repeated attempts for the current service instance; set mirror.endpoint to the final receiver URL. A Gateway restart probes the configured endpoint once again.

1,140 words · updated Aug 25, 2026