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_TOKENis 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:
- Fetches and verifies the signed auspex binary (cosign-verified against an embedded trust root — a tampered or unsigned binary fails closed).
- 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. - 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. - Launches the supervised daemon from a
SessionStarthook each session, which enrolls with Span using the provisioned token. - 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 tobashover 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 theirgit config user.email, then the optional bakedAUSPEX_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 showshould report the token as set and a work email resolved.auspex statusshould 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 confirmAUSPEX_CLOUD_TOKENis present inline in the setup script. Also confirm egress toagent-traces.span.appis 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 yourAUSPEX_BASE_URLhost. SetAUSPEX_VERIFY=checksumto drop the cosign/Sigstore egress. - Events unattributed —
CLAUDE_CODE_USER_EMAILand git identity were both unavailable; setAUSPEX_CLOUD_WORK_EMAILinline 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.