xray

module
v0.4.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 12, 2026 License: Apache-2.0

README

xray

Build CodeQL OpenSSF Scorecard SLSA 3 govulncheck License

xray is a read-only extractor that produces a portable engineering-metrics artifact from a client's git, GitHub, CI, and error-tracker systems.

  • Captures: commits, PRs, reviews, CI runs, deploys, incidents — structural data and declared configuration / tooling manifests, never application logic.
  • Produces: a single .tar.gz (SQLite + JSON manifest) — verifiable SHA256, no secrets.
  • Touches: GitHub, GitHub Actions, CircleCI, Sentry, Bugsnag, Honeycomb — read-only, even when tokens hold write scope.
  • Doesn't do: application-logic capture, per-individual rankings, daemon mode, scheduled runs.

[!IMPORTANT] xray runs inside a customer environment against the customer's own credentials. The artifact contains no source code and no secrets. Security review: docs/security.md · docs/threat-model.md. Vulnerability disclosure: SECURITY.md.

Design

xray is engineered against five non-negotiable constraints. The Trust documents below show how the implementation upholds each.

  • Independent. Runs buyer-side under the customer's operator and credentials. No vendor telemetry, no sales channel, no daemon mode.
  • System-level over time. Team-level and system-level granularity, enforced in the schema. No per-individual rollups anywhere.
  • Hypothesis-anchored. The window and connector set are chosen against a stated question; extraction_provenance records what was asked of every endpoint.
  • Brackets the AI-adoption inflection. harness_artifacts.first_seen_at records when each AI-tool config file (CLAUDE.md, .cursor/rules, .github/copilot-instructions.md) first appeared in repo history. Flow metrics join against the inflection inside one extract.
  • Source-free. Reads declared configuration and tooling manifests; never application logic.

Trust

xray is intended to be run inside the customer's environment by the customer's own operator, against the customer's own credentials, and the artifact it produces is meant to survive a security review. The four documents below describe what the binary does, what it cannot do, and what a representative run actually looks like.

  • docs/security.md — what is captured, what is not, and the guarantees the binary makes (read-only, no application logic, no secrets in the artifact, team-level only, logs).
  • docs/threat-model.md — one-page trust boundaries, attack surface, malicious-binary and leaked-artifact analysis.
  • docs/sample-manifest.json — a real manifest.json from a clean single-repo run against goreleaser/chglog, the same target /ready uses for smoke. Real row counts, real extraction_provenance block. Failure-mode endpoint states are documented in docs/security.md rather than reproduced here.
  • docs/sample-run.log — the matching .log file demonstrating no tokens, per-phase logs, and the post-run artifact summary.
  • docs/engagement-guide.md — the consultant-side counterpart: what happens to the artifact after you send it. Public so the methodology stays auditable.

Install

macOS
brew tap kmcd/xray https://github.com/kmcd/xray
brew install kmcd/xray/xray
Linux
curl -sSfL https://raw.githubusercontent.com/kmcd/xray/main/scripts/install.sh | sh

The script detects OS and architecture, downloads the latest release archive, verifies its sha256 against checksums.txt, and installs to /usr/local/bin/xray. Set XRAY_INSTALL_DIR=$HOME/.local/bin to install without sudo — make sure that directory is on your PATH. Set XRAY_VERIFY_COSIGN=1 to additionally verify the cosign signature (requires cosign on PATH).

Windows
scoop bucket add xray https://github.com/kmcd/xray
scoop install xray
Manual download

Pick the archive for your platform from the releases page and extract xray onto your PATH. For air-gapped or security-team installs, verify the cosign signature first — see Verifying the binary. For corporate proxy, custom CA, and firewall configuration, see docs/enterprise.md.

Go developers
go install github.com/kmcd/xray/cmd/xray@latest
Prerequisites

xray shells out to the system git binary for repository clones over HTTPS. Make sure git has credentials for github.com before running xray check or xray run. If gh is installed, the one-liner is:

gh auth setup-git

Otherwise, configure a credential helper (git credential-osxkeychain, git-credential-manager, or an embedded PAT in ~/.git-credentials). xray check reports a fix hint when this step is missing.

Usage

The default flow: configure → validate → run → export.

1. Configure
# Scaffold a starter config from a GitHub org's repos.
xray init --org my-org --token "$GITHUB_TOKEN"

# Or probe live connector data first and seed mappings automatically.
# Set env vars for each connector you want to probe, then:
xray init --org my-org --probe --out xray.toml.draft

Hand-edit the generated file: connector tokens, project mappings, team layout. The file stays on the operator's machine — never committed to git, never shared back to the consultant.

2. Validate and check
# Syntactic + schema check, offline. Defaults to ./xray.toml; pass an
# explicit path to point at a different config.
xray validate

# Live preflight against configured connectors (auth, rate limits, scope).
xray check
3. Run
# Full extraction. Produces ./xray-export-<UTC-timestamp>.tar.gz with a
# sibling .log file mirroring stderr (suppress with --no-run-log). See
# the sample-run block below the code for live TTY output.
xray run

# Machine-readable output. One NDJSON event per progress tick, terminated
# by a {"kind":"run_summary",...} object on stdout. See docs/spec.md.
xray run --output json | jq .

# Quiet success: only the artifact path is written to stdout.
xray run --output quiet
Sample run (live TTY output)

On a TTY, the default (--output auto) renders a live (repo × connector) status grid:

xray run · elapsed 04:12 · ETA 14:47 ±2m · 3/4 workers

repo                clone           github           gh_actions       sentry
kmcd/foo            ✔ done          ✔ 4213 rows      ● gh_actions     ✔ 312 rows
kmcd/bar            ✔ done          ● prs            ▢ pending        🔒 inaccessible
kmcd/baz            ● clone         ▢ pending        ▢ pending        ▢ pending

Non-TTY (CI, pipe to file) falls back to a stderr log with one line per phase boundary; force the log explicitly with --output log.

Exit codes: 0 clean, 1 config / pre-flight error, 2 partial run (artifact produced, connector error recorded in manifest), 3 fatal. See docs/spec.mdxray run → "Exit codes".

4. Export

The run produces two files in the working directory:

  • xray-export-<UTC-timestamp>.tar.gz — the artifact (SQLite + JSON manifest)
  • xray-export-<UTC-timestamp>.log — the run log (mirrors stderr)

Inspect manifest.json inside the archive before sending — it lists every connector's status, row counts, and per-endpoint errors. No source content, no secrets. Sample: docs/sample-manifest.json.

The full configuration reference and behaviour spec live in docs/spec.md. The output schema is documented in docs/schema.md. Agent-facing constraints (invariants, non-goals, schema-versioning rules) live in CLAUDE.md.

Compatibility

Pre-1.0, the schema is unstable; minor version bumps may introduce breaking schema changes. The analyser refuses to load artifacts at an unknown schema_version. Per-release changes that affect downstream consumers are tracked in CHANGELOG.md.

xray version schema_version
0.1.0 1
0.2.0 1
0.2.1 1
0.2.2 1
0.3.0 2
0.4.0 2
0.4.1 2
0.4.2 2
0.4.3 2
0.4.4 2

0.3.0 is the first release at schema_version = 2. Analysers pinned to schema_version = 1 will refuse to load 0.3.0+ artifacts — see the CHANGELOG for the author-handle semantics shift driving the bump.

Verifying the binary

Verify the cosign signature on checksums.txt, then verify the archive against the checksum.

VERSION=0.4.4
OS=linux           # or darwin, windows
ARCH=amd64         # or arm64 (not available on windows)

base=https://github.com/kmcd/xray/releases/download/v${VERSION}
curl -LO ${base}/xray_${VERSION}_${OS}_${ARCH}.tar.gz
curl -LO ${base}/checksums.txt
curl -LO ${base}/checksums.txt.sig
curl -LO ${base}/checksums.txt.pem

cosign verify-blob \
  --certificate-identity-regexp 'https://github.com/kmcd/xray/.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate checksums.txt.pem \
  --signature checksums.txt.sig \
  checksums.txt

sha256sum -c --ignore-missing checksums.txt
tar -xzf xray_${VERSION}_${OS}_${ARCH}.tar.gz
sudo mv xray /usr/local/bin/
Verifying provenance

Each release ships a single SLSA L3 build provenance attestation (xray.intoto.jsonl) generated by the SLSA GitHub generator. The file lists every release artifact as a subject (binaries, archives, SBOMs) so one download verifies any platform you pick. Each archive also ships an SPDX-JSON SBOM (*.spdx.json). Verify the attestation with slsa-verifier:

curl -LO ${base}/xray.intoto.jsonl

slsa-verifier verify-artifact \
  --provenance-path xray.intoto.jsonl \
  --source-uri github.com/kmcd/xray \
  --source-tag "v${VERSION}" \
  "xray_${VERSION}_${OS}_${ARCH}.tar.gz"

Security

Report vulnerabilities privately — see SECURITY.md.

License

Apache-2.0. See LICENSE.

xray is a read-only extraction tool. It never writes to any remote system and never stores credentials or source content in the output artifact.

FAQ

Can I run this against repositories with sensitive history?
Yes. xray reads git metadata — SHAs, timestamps, author handles, file paths, numstat — plus declared configuration and tooling manifests (workflow YAML, dependency manifests, AI-harness config files). It never reads application logic. No diff text, no commit bodies, no application source is read or stored. See the full capture inventory in docs/security.md.

What if a provider returns 403 on a required endpoint?
The endpoint records accessible: false with the reason and emits no rows. The analyser treats absence as unknown, not no signal — a critical distinction for analyses that depend on data presence. The run continues. See docs/security.md.

What happens if I revoke the token mid-run?
The next API call returns 401. The connector records accessible: false on that endpoint and continues; subsequent calls are recorded identically. The run completes with exit code 2 (partial — artifact produced, errors in manifest). See docs/security.md.

How do I verify the artifact has no secrets in it before sending?
Unpack the .tar.gz. manifest.json contains row counts, endpoint status, and provenance metadata — no credentials. A real example is at docs/sample-manifest.json.

What is in manifest.json vs. the SQLite database?
manifest.json is the run summary: schema version, extraction window, connector versions, per-endpoint access status, row counts, and errors. The SQLite DB is the metrics: commits, PRs, reviews, CI builds, error rates, observability signals. Full schema: docs/schema.md.

Does the tool need network access from inside my VPC?
Outbound HTTPS to configured providers (GitHub, Sentry, etc.) and to github.com for repo cloning. No inbound ports, no callbacks. Egress-only. See docs/spec.md for the full connector list.

Can I keep the temp clones for inspection?
Pass --keep-clones to skip cleanup; clone paths are logged to stderr and recorded in the .log file. By default, clones are deleted after each repo finishes. See docs/spec.mdxray run → flags.

Why does xray run finish in under a second for Honeycomb on repeat runs?
The Honeycomb markers API returns the full marker history on every call with no server-side date filter. After the first run, xray caches the response under $UserCacheDir/xray/honeycomb/ (macOS: ~/Library/Caches/xray/honeycomb/; Linux: ~/.cache/xray/honeycomb/) with a 24-hour TTL. Pass --no-cache to force a full re-fetch.

Why a static binary instead of a script or container?
A single static binary has one thing to verify: one file, one SHA256, one cosign signature. No runtime dependencies to audit — no pip, no npm, no base image. See docs/threat-model.md.

Build from source

See CONTRIBUTING.md.

Directories

Path Synopsis
cmd
xray command
Package main implements the xray CLI subcommands.
Package main implements the xray CLI subcommands.
internal
archive
Package archive packages the SQLite database and manifest into the final .tar.gz artifact.
Package archive packages the SQLite database and manifest into the final .tar.gz artifact.
config
Package config parses and validates xray TOML configuration with line-numbered diagnostics.
Package config parses and validates xray TOML configuration with line-numbered diagnostics.
connector
Package connector defines the Connector and Sink interfaces and the Provenance struct returned by each extraction.
Package connector defines the Connector and Sink interfaces and the Provenance struct returned by each extraction.
connectors
Package connectors is the parent package for individual connector implementations (github, githubactions, circleci, sentry, bugsnag, honeycomb).
Package connectors is the parent package for individual connector implementations (github, githubactions, circleci, sentry, bugsnag, honeycomb).
connectors/bugsnag
Package bugsnag implements the Bugsnag Data Access API connector.
Package bugsnag implements the Bugsnag Data Access API connector.
connectors/circleci
Package circleci implements the CircleCI v2 API connector.
Package circleci implements the CircleCI v2 API connector.
connectors/github
Package github is the xray GitHub connector.
Package github is the xray GitHub connector.
connectors/githubactions
Package githubactions implements the GitHub Actions connector.
Package githubactions implements the GitHub Actions connector.
connectors/honeycomb
Package honeycomb implements the Honeycomb API connector.
Package honeycomb implements the Honeycomb API connector.
connectors/sentry
Package sentry implements the Sentry API connector.
Package sentry implements the Sentry API connector.
connectors/vcr
Package vcr provides a shared VCR (cassette-replay) test helper for connector packages that make real HTTP calls.
Package vcr provides a shared VCR (cassette-replay) test helper for connector packages that make real HTTP calls.
gitcli
Package gitcli wraps the system git binary: clone, log --numstat --name-status, and per-path log.
Package gitcli wraps the system git binary: clone, log --numstat --name-status, and per-path log.
manifest
Package manifest writes manifest.json including the extraction_provenance block that records what each connector returned per repo.
Package manifest writes manifest.json including the extraction_provenance block that records what each connector returned per repo.
model
Package model defines the canonical row structs, SQLite DDL, and schema_version constant for the metrics.sqlite artifact.
Package model defines the canonical row structs, SQLite DDL, and schema_version constant for the metrics.sqlite artifact.
postprocess
Package postprocess runs cross-cutting linkage passes against the populated metrics SQLite store after every connector has finished extracting and before the manifest is written.
Package postprocess runs cross-cutting linkage passes against the populated metrics SQLite store after every connector has finished extracting and before the manifest is written.
preflight
Package preflight builds a cost-preview Plan for an xray run without performing the run.
Package preflight builds a cost-preview Plan for an xray run without performing the run.
progress
Package progress defines the structured run-time event contract for xray's CLI output cluster (cli-ux).
Package progress defines the structured run-time event contract for xray's CLI output cluster (cli-ux).
ratelimit
Package ratelimit provides a shared exponential-backoff HTTP helper that honours X-RateLimit-* and Retry-After headers, with a 3-attempt and 60-second cumulative cap.
Package ratelimit provides a shared exponential-backoff HTTP helper that honours X-RateLimit-* and Retry-After headers, with a 3-attempt and 60-second cumulative cap.
run
Package run orchestrates an extraction: temp-dir lifecycle, worker pool, per-(repo, connector) dispatch, manifest assembly, and provenance.
Package run orchestrates an extraction: temp-dir lifecycle, worker pool, per-(repo, connector) dispatch, manifest assembly, and provenance.
store
Package store opens metrics.sqlite, applies the DDL, and exposes prepared inserts for the canonical tables.
Package store opens metrics.sqlite, applies the DDL, and exposes prepared inserts for the canonical tables.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL