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
-
Auth test privileged endpoint: Use the staging auth-test privileged endpoint to prove a live token and permission check.
(
resources:auth-test:portal#access)
Important boundaries
- Creating a client does not grant arbitrary Jounce data access.
- Local client IDs are public; automated-job secrets are confidential.
- Tokens are issued for staging only and currently expire after 15 minutes.
- No refresh tokens are issued by these self-service client profiles.
- Never share a client between workloads or between staging and production.