Detecting the Current User
Ricochet lets your apps and APIs identify the user making each request.
Each request, ricochet injects an X-Ricochet-User HTTP header containing a signed JSON Web Token (JWT) with a claim containing that user’s information.
Anonymous visitors to a public item get no header.
An app deployed to ricochet can use this JWT to tailor its behavior based on the authenticated user.
The user claim
Section titled “The user claim”The X-Ricochet-User token is a JWT whose claims describe the current user:
| Claim | Description |
|---|---|
sub | User ID as provided by your configured identity provider (IdP). |
name | User display name as configured in ricochet. |
email | User email, if provided by the configured IdP. |
role | User role on the ricochet server, one of: admin, developer, or consumer. |
groups | Array of group IDs the user belongs to. |
aud | Content ID of the item the token was generated for. This is never the slug. |
iat | Time the token was issued, in UTC. |
exp | Time the token expires, in UTC. This is 5 minutes after iat. |
Verifying the token
Section titled “Verifying the token”Ricochet sets RICOCHET_URL and RICOCHET_CONTENT_ID in your app’s environment.
Verify every token before you trust it:
-
Fetch the public key from
RICOCHET_URL/.well-known/jwks.json. -
Read the
X-Ricochet-Userheader from the incoming request. -
Verify the signature using the RS256 algorithm.
-
Check that
audmatches theRICOCHET_CONTENT_IDenvironment variable. -
Check that
exphas not passed.
The token has no iss claim, so do not make your JWT library require one.
If your library needs the key in PEM format, fetch it from RICOCHET_URL/api/v0/public-key.
Ricochet removes any X-Ricochet-User header a client sends, so a client cannot fake the token.
Shiny apps
Section titled “Shiny apps”Shiny reads the header once, when the session opens. The token expires 5 minutes later, so verify it at session start and keep the claims.
Decoding the token
Section titled “Decoding the token”Use a maintained JWT library rather than parsing the token by hand.
The examples below use jose in R and PyJWT in Python.
library(jose)
ricochet_url <- Sys.getenv("RICOCHET_URL")content_id <- Sys.getenv("RICOCHET_CONTENT_ID")
# fetch the public keyjwks <- yyjsonr::read_json_conn( file.path(ricochet_url, ".well-known", "jwks.json"), arr_of_objs_to_df = FALSE)pubkey <- read_jwk(jwks$keys[[1]])
# token is the value of the X-Ricochet-User headerclaims <- jwt_decode_sig(token, pubkey)
# verify the audience matches this content itemif (!identical(claims$aud, content_id)) { stop("Invalid `aud` claim.")}
claims$nameimport osimport jwtfrom jwt import PyJWKClient
ricochet_url = os.environ["RICOCHET_URL"]content_id = os.environ["RICOCHET_CONTENT_ID"]
# fetch the public keyjwks_url = f"{ricochet_url}/.well-known/jwks.json"jwks_client = PyJWKClient(jwks_url)
# token is the value of the X-Ricochet-User headersigning_key = jwks_client.get_signing_key_from_jwt(token)
# verify the jwtclaims = jwt.decode( token, signing_key.key, algorithms=[signing_key.algorithm_name or "RS256"], audience=content_id,)
claims["name"]How you read the X-Ricochet-User header depends on your framework.
Examples
Section titled “Examples”Have questions? Start a discussion on GitHub.