Skip to content

Security: PioneerSquareLabs/metergraphsdk

Security

SECURITY.md

Security Policy

This repository is the client SDK (metergraph on PyPI and npm) — the code that runs inside your application and wraps your OpenAI, Anthropic, or Gemini client. It does not include the ingest server, price catalog, or dashboard; those live in PioneerSquareLabs/metergraph, which has its own security policy covering storage, retention, and server-side access control.

Supported Versions

This project has one active release line (0.x, pre-1.0). Security fixes land on the latest published release of each package. There is no long-term support branch yet.

Reporting a Vulnerability

Please report suspected vulnerabilities privately through GitHub Security Advisories rather than opening a public issue. Include the affected version, a reproduction if you have one, and the impact as you understand it. We'll acknowledge new reports and work with you on a fix and coordinated disclosure timeline.

Threat Model

What the SDK sends, and when. With no METERGRAPH_APP_TOKEN set, the SDK sends nothing — capture is off by default until explicitly configured. Once configured, every wrapped call produces one row of usage metadata (tokens, latency, model, route/session/tag labels, a structural template hash) sent to METERGRAPH_INGEST_URL. In SDK 0.4, configured clients include a scrubbed provider request and normalized response by default. Applications can opt out globally with METERGRAPH_CAPTURE_TEXT=0, at initialization, or around an individual route or trace. Request and response are independently limited to 1 MiB of UTF-8 by default; applications can raise that limit with METERGRAPH_TEXT_MAX_BYTES or the initialization option. Credentials are stripped before anything is serialized, where they travel: known-sensitive request-level parameters (api_key, authorization, token, secret and similar, including at the top level of extra_body) and header and query containers (headers, extra_headers, extra_query and their defaults), which are dropped whole. Messages, tools and schemas are captured as sent, including a field whose name matches a credential's, such as a tool parameter called token: analysis replays that request, so it must match what the provider received. Values inside prompts and tool arguments are content, and follow the content controls above. See scrub_request() in python/src/metergraph/_template.py and scrubRequest() in typescript/src/template.ts.

Fail-open by design. Transport, DNS, or ingest failures are swallowed and never raise, block, or slow down the wrapped LLM call — this is a deliberate availability-over-completeness tradeoff. The practical implication: a network position that can black-hole traffic to the ingest endpoint can silently suppress your cost telemetry, but it cannot use that position to degrade or crash the host application.

Auth model. A single per-app bearer token (METERGRAPH_APP_TOKEN) is sent as Authorization: Bearer <token> on every ingest and config-poll request. The hosted default endpoint is HTTPS. If you self-host and point METERGRAPH_INGEST_URL at a plain http:// endpoint (as local development setups typically do), the token and any captured metadata — including request and response content — travel in plaintext on that path. Treat the token like any other API credential: scope it per application, and don't commit it.

Blast radius of a compromised or malicious ingest endpoint. Beyond reading whatever rows the SDK sends (and being able to replay the bearer token against that endpoint), a malicious or compromised endpoint controls the responses to the SDK's periodic config poll (GET /v1/config). That config directly drives model_for()/modelFor()'s return value — see choose_model() in python/src/metergraph/_config.py and typescript/src/config.ts — which callers are expected to pass straight into their provider's model parameter. A malicious config response can therefore steer which model an application actually calls. Nothing in the SDK executes or evaluates response content as code, so this is a model-selection integrity risk, not a code-execution one — but it's worth knowing if you're deciding how much to trust a self-hosted or third-party ingest endpoint.

Supply chain. Both packages have zero runtime dependencies. Provider SDKs (openai, @anthropic-ai/sdk, @google/genai) are optional peer dependencies you already depend on directly; this SDK does not pin or install them.

There aren't any published security advisories