STAGING ONLY — NOT PRODUCTION

Developer guide

Local applications

Local clients are public clients. Open the authorization request in the system browser, listen only on the registered loopback address, and use Authorization Code with PKCE S256, a one-time state, and an OIDC nonce.

GET https://auth.jouncereporting.com/oauth2/auth
  ?client_id=<your-client-id>
  &response_type=code
  &redirect_uri=<your-exact-loopback-callback>
  &scope=openid%20permission%3Acheck
  &audience=jounce-api
  &state=<random-one-time-state>
  &nonce=<random-one-time-nonce>
  &code_challenge=<base64url-sha256-verifier>
  &code_challenge_method=S256

Exchange the returned code without a client secret:

POST https://auth.jouncereporting.com/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&client_id=<your-client-id>
&code=<one-time-code>
&redirect_uri=<identical-loopback-callback>
&code_verifier=<original-verifier>

Validate the ID token signature and kid against the issuer JWKS, plus exact issuer, client audience, nonce, and timestamps. Keep the opaque access token in memory or server-side. Do not place tokens in URLs or browser local storage.

Automated jobs

Automated jobs use a separate service: client for each workload and environment. OAuth HTTP Basic requires the username and password components to be form-encoded before joining them. This is important because Jounce service IDs contain colons. Obtain a fresh short-lived access token for each run:

basic_user="$(python3 -c 'import sys; from urllib.parse import quote; print(quote(sys.argv[1], safe=""))' "$JOUNCE_CLIENT_ID")"
basic_password="$(python3 -c 'import sys; from urllib.parse import quote; print(quote(sys.argv[1], safe=""))' "$JOUNCE_CLIENT_SECRET")"
curl --fail --silent --show-error \
  --user "$basic_user:$basic_password" \
  --data-urlencode grant_type=client_credentials \
  --data-urlencode scope=permission:check \
  --data-urlencode audience=jounce-api \
  https://auth.jouncereporting.com/oauth2/token

Send the resulting token as Authorization: Bearer <token>. The target API—not the job—must derive the protected resource and operation, validate audience and scope, and make the live Keto check.

Current self-service task catalog

Important boundaries