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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| sentry_viewercontext-0.1.0.tar.gz | 9.4 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.