This reference lists package-wide options for network requests,
logging, and validation. Set options near the top of app.R,
before creating the provider and client. The defaults apply when an
option is unset.
For example, allow a slow provider up to ten seconds per HTTP request:
options(shinyOAuth.timeout = 10)Times are in seconds unless a setting explicitly
says milliseconds. Options affect the R process; use
oauth_client() and oauth_module_server()
arguments for settings that belong to one client or module. See Usage for app setup.
check_oauth21() is an opt-in, read-only assessment
pinned to OAuth 2.1 draft 16. Ruleset 1.1.0 reports
requirement sources: OAuth core, OIDC, extensions, security guidance,
and package or application policy. Recommendations do not change the
mandatory configuration verdict. Existing OAuth 2.0 authentication
methods and callback choices remain available. For example, Basic/body
client authentication can pass while receiving advice to consider
asymmetric methods. Distinct callback routes remain valid when issuer
identification is unavailable, and localhost callbacks
remain supported with advice to prefer a loopback IP.
Callback capacity advice uses local field defaults and an 8000-byte minimum envelope as package thresholds, not numeric OAuth 2.1 requirements. Test the complete encoded query or form body against package, proxy and browser limits: include parameter names, separators, fixed application parameters, percent encoding, state, issuer and JARM. An aggregate floor cannot guarantee that all decoded fields fit simultaneously. Back-channel redirect blocking is package policy motivated by credential confidentiality; the draft’s browser redirect rules are a separate requirement.
Logging
-
options(shinyOAuth.audit_hook = function(event){ ... })– receive structured audit and error events -
options(shinyOAuth.audit_include_http = FALSE)– exclude HTTP request details from audit events (default:TRUE) -
options(shinyOAuth.audit_include_raw_session_token = TRUE)– include the rawshiny_session[["token"]]in native audit-hook payloads. By default, hooks receive onlyshiny_session[["session_token_digest"]] -
options(shinyOAuth.audit_redact_http = FALSE)– disable automatic redaction of sensitive data in audit events (default:TRUE). Debug only: raw mode can expose cookies, authorization headers, codes, state values, and client IP addresses -
options(shinyOAuth.telemetry_path_scrubber = function(path) NULL)– optionally return an approved route template for audit and OTel paths. Paths are omitted by default. ReturnNULLfor unknown routes; remove identifying segments and make the function idempotent. Input is bounded to 2048 bytes and output to 512 bytes. -
options(shinyOAuth.audit_digest_key = ...)– shared key of at least 32 bytes for HMAC-SHA256 digests used in audit/OTel attributes. Invalid configured keys cause an error; by default, ‘shinyOAuth’ generates a random per-process key when this is not configured -
options(shinyOAuth.otel_tracing_enabled = FALSE)– disable ‘shinyOAuth’ OpenTelemetry span creation and async trace-context propagation. Default:TRUE -
options(shinyOAuth.otel_logging_enabled = FALSE)– disable ‘shinyOAuth’ OpenTelemetry log emission. Default:TRUE -
options(shinyOAuth.otel_include_authorization_details = TRUE)– include raw scope names, claim targets, and ACR values in telemetry. Default:FALSE(counts only). These fields may be sensitive and have high cardinality.
See the audit logging vignette for details about audit hooks, and the OpenTelemetry vignette for more details about logs and traces via OpenTelemetry.
Validation and URL policy
options(shinyOAuth.access_token_cnf = "opaque")– never decode access tokens to obtain sender-binding metadata. DPoP and mTLS still checkcnffrom token responses and introspection and present their configured sender credentials. The compatibility default"jwt"inspects JWTcnfwithout validating the access-token signature; select it only where that representation is agreed with the provider. This option is propagated to async workers. Requiring observed binding remains a separate client policy (dpop_require_observed_cnformtls_require_observed_cnf).options(shinyOAuth.leeway = 30)– default clock skew leeway (seconds) for ID tokenexp/iat/nbfchecks and state payloadissued_atfuture checkoptions(shinyOAuth.max_id_token_lifetime = 86400)– maximum ID token lifetime in seconds (exp - iat). This is an additional package check beyond the OIDC expiry check. Default86400(24 hours). Set toInfto disable the checkoptions(shinyOAuth.allowed_non_https_hosts = c("localhost", "127.0.0.1", "::1", "[::1]"))- allows these hosts to usehttp://in non-OIDC URL checks; it does not relax OIDC discoveryoptions(shinyOAuth.allow_insecure_oidc_loopback = TRUE)– development-only opt-in for OIDC issuer and endpoint URLs on HTTP loopback origins; production OIDC metadata URLs must use HTTPSoptions(shinyOAuth.allowed_hosts = c())– when non‑empty, restricts accepted hosts to this whitelistoptions(shinyOAuth.allow_hs = TRUE)– opt‑in HMAC validation for ID tokens (HS256/HS384/HS512). Requires a strictly server‑sideclient_secretoptions(shinyOAuth.client_assertion_ttl = 120L)– lifetime in seconds for JWT client assertions used withclient_secret_jwtorprivate_key_jwttoken endpoint authentication. Finite values below 60 seconds are coerced to 60 seconds, finite values above 300 seconds are clamped to 300 seconds, andNAor non-finite values fall back to the 120-second defaultoptions(shinyOAuth.state_fail_delay_ms = 0)– delay in milliseconds before state parsing or decryption failures. Defaults to0(no delay). A positive number sets a fixed delay; two numbers, such asc(10, 30), set bounds for a randomized delay. Positive delays sleep synchronously and block the Shiny worker, including initial state validation withasync = TRUE. The delay adds timing noise but does not provide constant-time validation.
Note on allowed_hosts: patterns support globs
(*, ?). Using a catch‑all like
"*" matches any host and effectively disables endpoint host
restrictions (scheme rules still apply). Avoid this unless you truly
intend to accept any host; prefer pinning to your domain(s), e.g.,
c(".example.com").
Advanced parameter overrides
By default, ‘shinyOAuth’ blocks certain security-critical parameters
from being passed via extra_auth_params,
extra_token_params, and extra_token_headers.
This helps prevent accidental misconfiguration that could break state
binding, PKCE, or client authentication.
Set the callback format with
oauth_client(response_mode = ...).
If you have a specific, advanced use case where you need to override one of these blocked parameters, you can unblock them using the following options:
-
options(shinyOAuth.unblock_auth_params = c("redirect_uri"))– allows replacing the specified authorization URL parameters. Default blocked:response_type,client_id,redirect_uri,state,request_uri,request,scope,code_challenge,code_challenge_method,nonce,claims - Transaction and credential fields can never be unblocked:
state,nonce,client_id,code, all PKCE fields,refresh_token,client_secret,client_assertion,client_assertion_type,request,request_uri,response_type, andgrant_type. Allowed overrides replace existing names case insensitively; they do not append a duplicate protocol parameter. -
options(shinyOAuth.unblock_token_params = c(...))– allows replacing the specified token exchange parameters. Default blocked:grant_type,code,redirect_uri,code_verifier,client_id,client_secret,client_assertion,client_assertion_type -
options(shinyOAuth.unblock_token_headers = c("authorization"))– allows overriding the specified token exchange headers (case-insensitive). Default blocked:Authorization,Cookie
Async timeout (mirai)
-
options(shinyOAuth.async_timeout = 10000)– per-task timeout in milliseconds for mirai async tasks. When using mirai with dispatcher (the default), timed-out tasks are automatically cancelled and resolve as a mirai error. UseNULL(the default) for no timeout, or a whole number from 0 to 2147483647. Ignored when falling back to the ‘future’ backend
Async condition replay
-
options(shinyOAuth.replay_async_conditions = FALSE)– whenFALSE, warnings and messages captured from async workers are silently discarded instead of being re-emitted on the main R process. Default isTRUE(replay all captured conditions). Useful if worker diagnostics are too noisy or handled separately viaaudit_hook
Token lifetime fallback
-
options(shinyOAuth.default_expires_in = 3600)– fallback token lifetime (in seconds) when the provider omitsexpires_infrom the token response
HTTP settings (timeout, retries, user agent)
options(shinyOAuth.tls_min_version = "1.2")- optionally require TLS 1.2 or later on package-owned HTTPS requests."1.3"requires TLS 1.3 or later;NULL(default) retains the linked curl/TLS backend’s defaults. Applies before discovery and to token, PAR, JWKS, UserInfo and resource requests, including async workers. A stronger supplied minimum and a compatible supplied maximum survive; a conflicting maximum or disabled certificate/hostname verification raises an error when a minimum is selected. Custom CA settings remain usable. The setting is bound to pending login transactions, so change it before initiating login. It does not configure browser/proxy TLS or disallow HTTP development endpoints. Older wolfSSL backends require curl 8.10.0 or later to apply minimum-version semantics. Actual negotiated connections remain runtime evidence; an absent option alone says nothing about their TLS version.options(shinyOAuth.timeout = 5)– default HTTP timeout (seconds) applied to all outbound requests (discovery, JWKS, token exchange, userinfo). Increase if your provider/network is slow. Values beyond curl’s supported timeout range are cappedoptions(shinyOAuth.retry_max_tries = 3L)– maximum attempts for retryable requests after network errors or HTTP 408, 429, or 5xx responses. Authorization-code exchange and refresh are not automatically retried, apart from a single DPoP nonce challenge retryoptions(shinyOAuth.dpop_nonce_max_bytes = 4096L)– maximum DPoP nonce size in bytes. RFC 9449 sets no length limit; this local resource limit is configurable from 1 to 65536 bytes and is propagated to async workers. A response exceeding it raises a specific error without exposing the nonce. Raise it if your provider legitimately issues larger noncesoptions(shinyOAuth.retry_backoff_base = 0.5)– base backoff in seconds used for exponential backoff with jitteroptions(shinyOAuth.retry_backoff_cap = 5)– per‑attempt cap on backoff seconds (before jitter)options(shinyOAuth.retry_after_cap = 60)– maximum synchronous sleep in seconds for a server-providedRetry-Aftervalue; this is separate from the client-side backoff capoptions(shinyOAuth.retry_status = c(408L, 429L, 500:599))– HTTP statuses considered transient and retriedoptions(shinyOAuth.user_agent = "shinyOAuth/<version> R/<version> httr2/<version>")– override the default User‑Agent header applied to all outbound requests. By default this string is built dynamically from the installed package/runtime versions; set a custom string here if your organization requires a specific formatoptions(shinyOAuth.allow_redirect = FALSE)– whenFALSE(default), all sensitive HTTP requests (token exchange, refresh, introspection, revocation, userinfo, OIDC discovery, JWKS) refuse to follow redirects and reject 3xx responses. This prevents authorization codes, tokens, and PKCE verifiers from leaking to redirect targets. Set toTRUEonly when you deliberately accept that redirect-following risk for a specific deployment; this opt-in is honored in all sessionsoptions(shinyOAuth.max_body_bytes = 1048576)– maximum response body size (bytes, default 1 MiB) accepted from OAuth endpoints and resource requests. Increase this if an API legitimately returns larger payloads. The limit also applies after gzip decompression; other content encodings are rejected. Values above R’s supported binary-read size are capped
State store
-
options(shinyOAuth.allow_non_atomic_state_store = TRUE)– allow a shared state store without atomic[["take"]]()to use separate[["get"]]()and[["remove"]]()calls. DefaultFALSE: such a store causes an error. WithTRUE, the package warns once and proceeds, but concurrent requests may reuse a login entry. Use an atomic shared store for production; seecustom_cache().
Size caps
State envelope
-
options(shinyOAuth.state_max_token_chars = 8192)– maximum allowed length of the base64url-encodedstatequery parameter -
options(shinyOAuth.state_max_wrapper_bytes = 8192)– maximum decoded byte size of the outer JSON wrapper (before parsing) -
options(shinyOAuth.state_max_ct_b64_chars = 8192)– maximum allowed length of the base64url-encoded ciphertext inside the wrapper -
options(shinyOAuth.state_max_ct_bytes = 8192)– maximum decoded byte size of the ciphertext before attempting AES-GCM decrypt
These prevent maliciously large state parameters from causing excessive CPU or memory usage during decoding and decryption.
Callback query
-
options(shinyOAuth.callback_max_code_bytes = 8192)– maximum decoded byte length of thecodecallback parameter across direct, GET/POST bridge, module and JARM paths. Explicit lower or higher limits remain effective; values are rejected rather than truncated -
options(shinyOAuth.callback_max_state_bytes = 8192)– maximum byte length of thestatequery parameter (outer token string) -
options(shinyOAuth.callback_max_error_bytes = 256)– maximum byte length of theerrorquery parameter -
options(shinyOAuth.callback_max_error_description_bytes = 4096)– maximum byte length of theerror_descriptionquery parameter -
options(shinyOAuth.callback_max_error_uri_bytes = 2048)– maximum byte length of theerror_uriquery parameter -
options(shinyOAuth.callback_max_iss_bytes = 2048)– maximum byte length of theissquery parameter (RFC 9207 issuer identification) -
options(shinyOAuth.callback_max_query_bytes = <derived>)– maximum total byte length of the raw query string. HTTP UI wrappers apply this budget to every request, including ordinary application queries and hosted Request Object requests, before routing or parsing. -
options(shinyOAuth.callback_max_browser_token_bytes = 256)– maximum byte length of thebrowser_tokenargument accepted byhandle_callback() -
options(shinyOAuth.callback_max_form_post_body_bytes = <derived>)– maximum byte length of the rawform_postcallback body before parsing -
options(shinyOAuth.callback_max_form_post_handle_bytes = 128)– maximum byte length of the transientshinyOAuth_form_posthandle query parameter -
options(shinyOAuth.callback_max_form_post_id_bytes = 256)– maximum byte length of the transientshinyOAuth_form_post_idmodule-id query parameter
These limits reject oversized callback URLs and POST bodies before they cause excessive processing or logging. Keep the defaults unless a legitimate provider response needs more space.
Generated login state must fit both
shinyOAuth.callback_max_state_bytes and the state envelope
limits above. Their outer-token defaults both allow 8192 bytes
(base64url state is ASCII). Lowering either limit can restrict ordinary
logins with many scopes or other state metadata.
prepare_call() checks both budgets before storing pending
login state, publishing a Request Object, or sending PAR. Increasing
only one limit does not override the other.
Local debugging
options(shinyOAuth.skip_browser_token = TRUE)– skip browser cookie binding in tests or interactive sessionsoptions(shinyOAuth.skip_id_sig = TRUE)– skip ID token signature verification in tests or interactive sessionsoptions(shinyOAuth.allow_unsigned_userinfo_jwt = TRUE)– accept unsigned (alg=none) UserInfo JWTs in tests or interactive sessions; outside those contexts ‘shinyOAuth’ errors instead of honoring itoptions(shinyOAuth.debug = TRUE)– re‑raise errors during token exchange-
options(shinyOAuth.expose_error_body = TRUE)– include sanitized HTTP bodies, claim values, and free-form error details in audit/OTel output and module diagnostics during tests or interactive debugging. Details omit URL credentials and control characters and are capped at 512 UTF-8 bytes per field; they may still contain sensitive information. Production processes keep these details disabled.HTTP and transport condition contexts use the same URL and diagnostic policy. Transport parents retain their error classes but omit original request/response objects, calls, backtraces, and nested parents. Their messages are withheld by default; the exposure option enables only sanitized messages. JWKS metadata failures also withhold underlying diagnostics by default.
Don’t enable these options in production. They disable key security checks or alter error behavior, and are intended for local testing/debugging only.