Capture Claude Code Cloud Agents with auspex

Last updated: September 2, 2026

This guide is for teams that run Claude Code cloud agents — the Anthropic-hosted Linux VMs behind Claude Code on the web (claude.ai/code), claude --cloud, the Claude tag, and routines — and want that agent activity captured in Span, just like work on a laptop.

It installs the Span agent (auspex) on the cloud VM at environment setup, wires one Claude capture hook tier, launches the supervised daemon in-session, and enrolls with Span. Setup is a small recipe you paste into your Claude cloud environment.

This is for cloud agents. For engineers running Claude Code on their own machine, use the macOS or Windows install guides (or your MDM). You can run both — auspex captures each surface once.

⚠️ Important: the org token is entered in plain text in your setup script

Claude Code cloud environments do not provide a secret store that a setup script can read. As a result, this recipe requires you to place your AUSPEX_CLOUD_TOKEN (the Span org token) inline, in plain text, in the environment's setup-script configuration. This is a deliberate workaround for a platform limitation, not our preferred design.

Why the exposure is limited: AUSPEX_CLOUD_TOKEN is a low-privilege token that can do only two things: post telemetry events to your Span ingest endpoint, and read (never modify) your organization's auspex capture/hook configuration. It grants no access to any captured data (traces, prompts, file contents), no write access to your Span configuration, and no other authentication of any kind. So the blast radius of a leak is bounded to spurious event ingestion and read-only visibility of your capture configuration. Still, treat the setup configuration as sensitive (it's admin-controlled), and rotate the token with your Span administrator if you suspect it has been exposed.

We are tracking Anthropic's addition of a proper encrypted secret store; when it lands, this workaround goes away. Until then, the steps below are the supported path.

How it works

Each Claude cloud session runs in a configurable environment: a network-access level and a setup script that runs once, as root, before the session starts. Because that setup script runs before the session — and Claude injects no session secrets — the recipe splits the work across the setup phase and an in-session hook. On each agent VM it:

  1. Fetches and verifies the signed auspex binary (cosign-verified against an embedded trust root — a tampered or unsigned binary fails closed).
  2. Places one Claude hook tier — the managed tier (/etc/claude-code/managed-settings.d/), the only tier that fires under Claude's managed-hooks lockdown — so events are never double-captured.
  3. Provisions the org token into auspex's identity file at setup (auspex auth set), so the in-session daemon can enroll with no session secret required.
  4. Launches the supervised daemon from a SessionStart hook each session, which enrolls with Span using the provisioned token.
  5. Attributes events to the engineer who dispatched the agent — resolved in-session from Claude's CLAUDE_CODE_USER_EMAIL, then the repo's git identity, then an optional baked fallback.

Token usage, turn enrichment, and sub-agent metrics ride along automatically via auspex's built-in session-log reader once the daemon is running.

Before you start

  • Admin access to your Claude Code cloud-agent environment settings (an organization admin, to create a shared/default environment and set its setup script). See Anthropic's Configure cloud environments.
  • Your Span org auth token (AUSPEX_CLOUD_TOKEN, from your Span administrator — the org-wide telemetry token, not a personal access token). Read the disclaimer above first.
  • The auspex download host (https://auspex.span.app, or the host your Span rep provided).

Step 1: Create a default cloud environment with the setup script

Because Claude does not support committing environment setup to your repository, you configure this once at the environment level. Create (or edit) a cloud environment, set its setup script to the block below, and make it your Organization's default cloud environment so that every new chat/session inherits it automatically — nothing is committed to any repo.

The reference recipe lives in the public auspex-distribution repository. Its scripts are cosign-signed and published as GitHub Release assets (claude-cloud-install.sh, claude-cloud-session-start.sh, claude-cloud-preflight.sh), so the setup fetches them from an immutable, signed URL.

Set your environment's setup script to:

set -euo pipefail
export AUSPEX_BASE_URL="https://auspex.span.app"     # your auspex download host (from onboarding)
export AUSPEX_CLOUD_TOKEN="span_REPLACE_ME"          # your Span org token — see the disclaimer above
curl -fsSL https://github.com/Attuned-Corp/auspex-distribution/releases/latest/download/claude-cloud-install.sh -o /tmp/claude-cloud-install.sh && bash /tmp/claude-cloud-install.sh

latest/download tracks the newest release; pin a specific tag (.../releases/download/<tag>/claude-cloud-install.sh) for a reproducible setup. Each asset ships a .cosign.bundle so you can verify it before running (see the recipe README).

Download-then-run, not curl … | bash. Piping the installer to bash over stdin can let the script (or a child process) consume the rest of the piped script from stdin. Fetch to a temp file first, then run it — as shown above.

Step 2: Inline configuration

The setup script reads these from its own environment (export them inline, as above — there are no session secrets to inject them another way):

Name Required Value
AUSPEX_BASE_URL yes your auspex download host, e.g. https://auspex.span.app
AUSPEX_CLOUD_TOKEN yes your Span org auth token — provisioned into auspex's identity file at setup (the in-session daemon enrolls from it). Entered in plain text — see the disclaimer at the top of this guide.
AUSPEX_CLOUD_WORK_EMAIL optional a baked attribution fallback; the session prefers Claude's per-session CLAUDE_CODE_USER_EMAIL
AUSPEX_VERSION optional pin a signed release tag; leave unset to install the latest
AUSPEX_VERIFY optional cosign (default) or checksum
  • Attribution needs no configuration. In each session the recipe resolves the dispatching engineer's work email from Claude's CLAUDE_CODE_USER_EMAIL, then their git config user.email, then the optional baked AUSPEX_CLOUD_WORK_EMAIL. Every tier is guarded; if none resolves, capture still runs — events are just unattributed.
  • All values are read at setup (before the session). Nothing needs to be visible in-session.

Step 3: Allowlist egress (only if your org restricts it)

Claude cloud's default Trusted network level does not include the Span ingest host, so set the environment to Full, or to Custom and allowlist the auspex endpoints plus the install-time fetch. The complete list — hostnames and IP ranges, how to shrink it, and the AUSPEX_VERIFY=checksum option to drop the cosign/Sigstore egress — is maintained in one place: see Network Access → auspex in Claude Code cloud agents in the security overview.

Step 4: Launch a normal cloud session

Launch a Claude cloud agent the way you normally would (Claude Code on the web, claude --cloud, the Claude tag, or a routine). Because the recipe lives in your default environment, every new session inherits it — the managed hooks and the SessionStart daemon launch are picked up automatically, with no bespoke base image and nothing to commit to the repo.

Step 5: Verify

Inside a running agent, run:

auspex auth show
auspex status --verbose --check-token

Or run the bundled preflight (resolved identity + the health report):

curl -fsSL https://github.com/Attuned-Corp/auspex-distribution/releases/latest/download/claude-cloud-preflight.sh -o /tmp/claude-cloud-preflight.sh && bash /tmp/claude-cloud-preflight.sh
  • auspex auth show should report the token as set and a work email resolved.
  • auspex status should report the daemon reachable, capture wired, the token valid, and a single placement tier (no double-capture).

Then have the agent do some work (edit files, run commands) and confirm the trace appears in the Span dashboard. If you don't see anything yet, ask your Span rep to enable Agent Traces for your org.

Limitations

  • Token in setup config: with no session secrets, the org token lives in the environment's setup-script configuration in plain text. It's a low-privilege token — a leak only permits posting telemetry events and reading (not modifying) your capture configuration, never reading captured data — so the blast radius is bounded; still treat the configuration as sensitive and rotate on suspected leak.
  • Environment caching: Claude snapshots the environment by repository + setup-script content. If you change the token or config, edit the setup script text (or start a fresh environment) so Claude re-runs setup rather than reusing an old snapshot.
  • Teardown: a burst of events in the final moments before the VM is torn down may not flush.
  • Attribution scope: the work email is the dispatching human, so an agent driven by multiple people is attributed to that identity.

Troubleshooting

  • No events in Span — run auspex auth show; if the token is not set, Claude likely reused a cached environment (bump the setup script or start a new environment so setup re-runs), and confirm AUSPEX_CLOUD_TOKEN is present inline in the setup script. Also confirm egress to agent-traces.span.app is allowed.
  • Setup failed fetching the binary (403 / blocked) — this is almost always egress: set the environment to Full network access, or (in Custom) allowlist github.com, objects.githubusercontent.com, and your AUSPEX_BASE_URL host. Set AUSPEX_VERIFY=checksum to drop the cosign/Sigstore egress.
  • Events unattributedCLAUDE_CODE_USER_EMAIL and git identity were both unavailable; set AUSPEX_CLOUD_WORK_EMAIL inline as a fallback.
  • Two of every event — a second hook tier is present. The recipe places only one; remove any Claude hooks you placed manually and let setup re-run.

If you're stuck, share the environment's setup log and the output of auspex status --verbose with the Span team.