Skip to main content

viewercontext

Caller identity propagated between Sentry services: who is acting (an Actor), and for which organization and project. Sentry mints it; other services verify it and pass it along.

One repo, two native implementations released together under one version:

Package Import
Python sentry-viewercontext (PyPI, internal PyPI) import sentry_viewercontext
Rust sentry-viewercontext (crates.io) use sentry_viewercontext::...

fixtures/ holds the wire contract. Both test suites run every case in it, so a change that makes the implementations disagree fails CI.

Python

from sentry_viewercontext import (
    Actor,
    ActorType,
    ViewerContext,
    decode_jwt,
    encode_jwt,
    viewer_context_scope,
)

ctx = ViewerContext(Actor(ActorType.SERVICE_ACCOUNT, actor_id=9), organization_id=1)
token = encode_jwt(ctx, key=secret)  # value for the X-Viewer-Context header
ctx = decode_jwt(token, keys=[current, previous])  # picks the key by `kid`

with viewer_context_scope(ctx):
    ...  # get_viewer_context() returns ctx here

Rust

use sentry_viewercontext::{Actor, ActorType, ViewerContext, decode_jwt, encode_jwt, DEFAULT_LEEWAY, DEFAULT_TTL};

let mut ctx = ViewerContext::new(Actor::new(ActorType::ServiceAccount, Some(9)));
ctx.organization_id = Some(1);
let token = encode_jwt(&ctx, secret, DEFAULT_TTL)?;
let ctx = decode_jwt(&token, &[current, previous], DEFAULT_LEEWAY)?;

Rust has no ambient context; carry the ViewerContext in request extensions or task-locals.

Wire format (version 2)

{
  "version": 2,
  "actor": {"type": "agent", "id": 5, "delegated_user_id": 42, "superuser": {"expires_at": 1800000000}},
  "organization_id": 1,
  "project_id": 7,
  "organization_is_early_adopter": true
}

Only version and actor.type are required. Actor types: user, service_account, system, integration, agent, unknown. As a JWT it is signed HS256 with iat, exp, iss: "sentry" and a kid header (first 8 hex chars of the key's SHA-256). Superuser access caps exp at 5 minutes and at superuser.expires_at.

What a service does with a context (required org scope, permission checks, metrics, where signing keys come from) stays in that service.

Development

uv sync
uvx prek install                                   # or pre-commit; runs ruff, mypy, rustfmt, clippy, zizmor
uv run pytest --cov                                # 100% branch coverage required
cargo test
uv run python scripts/generate_token_fixtures.py  # after changing token cases

CI additionally runs Python 3.13 and 3.14 (Sentry's and Seer's versions), Rust on latest stable, cargo doc with warnings denied, and cargo publish --dry-run.

Releasing

Run the Release workflow with the new version. Craft bumps both manifests (scripts/bump-version.sh) and publishes to GitHub, PyPI, internal PyPI and crates.io.

License

FSL-1.1-ALv2, the same license as getsentry/sentry.

Metadata

Release files for sentry-viewercontext 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sentry-viewercontext 0.1.0
File Size Uploaded Provenance
sentry_viewercontext-0.1.0.tar.gz 9.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for sentry-viewercontext 0.1.0
File Interpreter ABI Platform
sentry_viewercontext-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 18.1 kB

Release files / sentry_viewercontext-0.1.0.tar.gz

Download URL sentry_viewercontext-0.1.0.tar.gz
Size 9.4 kB
Tags Source
SHA-256 checksum
How to use checksums
85dae1b91e52016799822f41d21136ad543d252a41a16e6f9ae03366a7b1076e
BLAKE2b-256 checksum
How to use checksums
877add36d0c7aff079e5f975499f0962c7255332369881933f0f727efaca3e4b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.2

Release files / sentry_viewercontext-0.1.0-py3-none-any.whl

Download URL sentry_viewercontext-0.1.0-py3-none-any.whl
Size 8.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
388161ccf93af22ed0c3bd6e48ac4875b05d096e6839edd68befe47ec8b15132
BLAKE2b-256 checksum
How to use checksums
4ab424baca202023ce00b3f87f26f7275b9fec489afadcac05d624e7c449dac9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.2

Security for sentry-viewercontext 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page