> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beacon.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Sharing via API Key

> Share agent sessions from CI, containers and headless machines with a Beacon API key

Where nobody can run `beacon login` (CI runners, containers, scheduled jobs, a server you reach over SSH), `beacon share` authenticates with a Beacon API key instead. The key works the same way everywhere `beacon share` runs, including the [`beacon-trace-share` skill](/sharing/agent-skills) and the [pre-push hook](/sharing/git-hooks).

## Create an API key

1. Sign in to beacon.sh and open **API Keys** in the dashboard ([beacon.sh/dashboard/api-keys](https://beacon.sh/dashboard/api-keys)).
2. Create a key with the **Publish shared traces** (`traces:write`) permission, which is all `beacon share` needs, including `refresh` and `--follow`. Choose an expiry.
3. Copy the key. It starts with `bcn_api_` and is shown only once.

Store it as a secret in your CI system, for example a GitHub Actions secret or a masked GitLab CI/CD variable named `BEACON_API_KEY`. Never commit it.

## Use the key

```bash theme={null}
export BEACON_API_KEY=bcn_api_...
beacon share --cwd . --json
```

No `beacon login` is needed. Prefer the environment variable to `--key`, which puts the key on the command line where process listings can see it.

`beacon share` uses the first credential available: `--key`, then a `beacon login` sign-in carrying `traces:write`, then `BEACON_API_KEY`. On a machine that is also signed in, pass `--key` to use the key. The key is sent only in the request's `Authorization` header to beacon.sh's API (`api.beacon.sh`), redirects are refused, and it is never printed. For a self-hosted Beacon service, set `BEACON_AUTH_URL` (or `--auth-url`) to that service, and `BEACON_API_URL` too if its API is on another host.

## Run the share in the agent's job

`beacon share` reads the session from the machine it runs on, so run it in the same job as the agent, after it. Claude Code and Codex CLI keep sessions in stores `beacon share` reads directly, so nothing else needs to be installed. For a runtime whose sessions Beacon reads only from its runtime log, start [Beacon CI telemetry](/cli/ci-start) before the agent and pass the CI log with `--log-path`.

## GitHub Actions

This workflow runs an agent on a pull request, shares its session, adds the link to the job summary, and comments it on the pull request:

```yaml title=".github/workflows/agent.yml" theme={null}
name: Agent
on:
  pull_request:
  workflow_dispatch:

jobs:
  agent:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
    steps:
      - uses: actions/checkout@v4

      - name: Install Beacon
        run: curl -fsSL https://github.com/asymptote-labs/agent-beacon/releases/latest/download/install.sh | bash

      - name: Run the agent
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: npx -y @anthropic-ai/claude-code --print "Fix the failing test and explain the change"

      - name: Share the agent session
        id: share
        if: always()
        env:
          BEACON_API_KEY: ${{ secrets.BEACON_API_KEY }}
        run: |
          out="$(beacon share --cwd . --harness auto --json)" || { echo "$out"; exit 0; }
          url="$(printf '%s' "$out" | jq -r '.data.shared_url')"
          echo "url=$url" >> "$GITHUB_OUTPUT"
          echo "### Agent session" >> "$GITHUB_STEP_SUMMARY"
          echo "$url" >> "$GITHUB_STEP_SUMMARY"

      - name: Link the session on the pull request
        if: github.event_name == 'pull_request' && steps.share.outputs.url != ''
        uses: actions/github-script@v7
        env:
          SHARE_URL: ${{ steps.share.outputs.url }}
        with:
          script: |
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: `Agent session: ${process.env.SHARE_URL}`,
            });
```

The link reaches the script through an environment variable rather than being written into it, so nothing in the share output can change what the script runs. A failed share leaves the job green (`exit 0`); remove that to make a missing trace fail the build.

## GitLab CI

```yaml title=".gitlab-ci.yml" theme={null}
agent:
  image: node:22
  variables:
    # BEACON_API_KEY and ANTHROPIC_API_KEY are masked CI/CD variables.
    GIT_DEPTH: "0"
  before_script:
    - apt-get update -qq && apt-get install -y -qq jq sudo
    - curl -fsSL https://github.com/asymptote-labs/agent-beacon/releases/latest/download/install.sh | bash
  script:
    - npx -y @anthropic-ai/claude-code --print "Fix the failing test and explain the change"
  after_script:
    - beacon share --cwd "$CI_PROJECT_DIR" --harness auto --json | tee beacon-share.json || true
    - echo "Agent session: $(jq -r '.data.shared_url // empty' beacon-share.json)"
  artifacts:
    when: always
    paths:
      - beacon-share.json
```

`after_script` runs in the same job even when the agent fails, so the session is still on disk.

## Docker

Install Beacon in the image and pass the keys in at run time:

```dockerfile title="Dockerfile" theme={null}
FROM node:22-slim
RUN apt-get update -qq && apt-get install -y -qq curl ca-certificates \
 && curl -fsSL https://github.com/asymptote-labs/agent-beacon/releases/latest/download/install.sh | bash
WORKDIR /app
COPY . .
CMD ["sh", "-c", "npx -y @anthropic-ai/claude-code --print \"$PROMPT\"; beacon share --cwd /app --harness auto --json"]
```

```bash theme={null}
docker run \
  -e ANTHROPIC_API_KEY \
  -e BEACON_API_KEY \
  -e PROMPT="Review this codebase for bugs" \
  my-agent-image
```

`-e NAME` without a value passes the variable from your shell, so the key is not written on the command line.

## Headless machines and SSH

```bash theme={null}
export BEACON_API_KEY=bcn_api_...
beacon share --cwd ~/src/app --json
```

## Tips

* Use `--json` in CI and read `data.shared_url` from the result.
* Use `--harness auto` when the job could run more than one runtime, or name the one it runs.
* Keep the default `direct` visibility, or use `--visibility private`, for sessions that touched proprietary code. Without a terminal, `public` needs `--yes`.
* Run `beacon share --print` once in the pipeline to read exactly what it uploads.
* Share after the agent finishes rather than with `--follow`: `--follow` needs the session to exist when it starts, and most CI runners stop background processes when their step ends.
* Revoke a key from **API Keys** on beacon.sh as soon as it is no longer needed.

## Related

> **[beacon share reference](/cli/share#credentials)**
>
> Credential order and every flag.

> **[Beacon CI telemetry](/cli/ci)**
>
> Capture agent runs in CI for runtimes without a session store.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.