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:
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.
options(shinyOAuth.audit_hook = function(event){ ... })
– receive structured audit and error eventsoptions(shinyOAuth.audit_include_http = FALSE) –
exclude HTTP request details from audit events (default:
TRUE)options(shinyOAuth.audit_include_raw_session_token = TRUE)
– include the raw shiny_session[["token"]] in native
audit-hook payloads. By default, hooks receive only
shiny_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 addressesoptions(shinyOAuth.telemetry_path_scrubber = function(path) NULL)
– optionally return an approved route template for audit and OTel paths.
Paths are omitted by default. Return NULL for 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
configuredoptions(shinyOAuth.otel_tracing_enabled = FALSE) –
disable ‘shinyOAuth’ OpenTelemetry span creation and async trace-context
propagation. Default: TRUEoptions(shinyOAuth.otel_logging_enabled = FALSE) –
disable ‘shinyOAuth’ OpenTelemetry log emission. Default:
TRUEoptions(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.
options(shinyOAuth.access_token_cnf = "opaque") –
never decode access tokens to obtain sender-binding metadata. DPoP and
mTLS still check cnf from token responses and introspection
and present their configured sender credentials. The compatibility
default "jwt" inspects JWT cnf without
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_cnf or
mtls_require_observed_cnf).
options(shinyOAuth.leeway = 30) – default clock skew
leeway (seconds) for ID token
exp/iat/nbf checks and state
payload issued_at future check
options(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. Default
86400 (24 hours). Set to Inf to disable the
check
options(shinyOAuth.allowed_non_https_hosts = c("localhost", "127.0.0.1", "::1", "[::1]"))
- allows these hosts to use http:// in non-OIDC URL checks;
it does not relax OIDC discovery
options(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 HTTPS
options(shinyOAuth.allowed_hosts = c()) – when
non‑empty, restricts accepted hosts to this whitelist
options(shinyOAuth.allow_hs = TRUE) – opt‑in HMAC
validation for ID tokens (HS256/HS384/HS512). Requires a strictly
server‑side client_secret
options(shinyOAuth.client_assertion_ttl = 120L) –
lifetime in seconds for JWT client assertions used with
client_secret_jwt or private_key_jwt token
endpoint authentication. Finite values below 60 seconds are coerced to
60 seconds, finite values above 300 seconds are clamped to 300 seconds,
and NA or non-finite values fall back to the 120-second
default
options(shinyOAuth.state_fail_delay_ms = 0) – delay
in milliseconds before state parsing or decryption failures. Defaults to
0 (no delay). A positive number sets a fixed delay; two
numbers, such as c(10, 30), set bounds for a randomized
delay. Positive delays sleep synchronously and block the Shiny worker,
including initial state validation with async = 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").
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,
claimsstate, nonce, client_id,
code, all PKCE fields, refresh_token,
client_secret, client_assertion,
client_assertion_type, request,
request_uri, response_type, and
grant_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_typeoptions(shinyOAuth.unblock_token_headers = c("authorization"))
– allows overriding the specified token exchange headers
(case-insensitive). Default blocked: Authorization,
Cookieoptions(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. Use NULL (the default) for no
timeout, or a whole number from 0 to 2147483647. Ignored when falling
back to the ‘future’ backendoptions(shinyOAuth.replay_async_conditions = FALSE) –
when FALSE, warnings and messages captured from async
workers are silently discarded instead of being re-emitted on the main R
process. Default is TRUE (replay all captured conditions).
Useful if worker diagnostics are too noisy or handled separately via
audit_hookoptions(shinyOAuth.default_expires_in = 3600) –
fallback token lifetime (in seconds) when the provider omits
expires_in from the token responseoptions(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 capped
options(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
retry
options(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 nonces
options(shinyOAuth.retry_backoff_base = 0.5) – base
backoff in seconds used for exponential backoff with jitter
options(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-provided
Retry-After value; this is separate from the client-side
backoff cap
options(shinyOAuth.retry_status = c(408L, 429L, 500:599))
– HTTP statuses considered transient and retried
options(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 format
options(shinyOAuth.allow_redirect = FALSE) – when
FALSE (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 to TRUE only when you deliberately accept that
redirect-following risk for a specific deployment; this opt-in is
honored in all sessions
options(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
options(shinyOAuth.allow_non_atomic_state_store = TRUE)
– allow a shared state store without atomic [["take"]]() to
use separate [["get"]]() and [["remove"]]()
calls. Default FALSE: such a store causes an error. With
TRUE, the package warns once and proceeds, but concurrent
requests may reuse a login entry. Use an atomic shared store for
production; see custom_cache().options(shinyOAuth.state_max_token_chars = 8192) –
maximum allowed length of the base64url-encoded state query
parameteroptions(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
wrapperoptions(shinyOAuth.state_max_ct_bytes = 8192) – maximum
decoded byte size of the ciphertext before attempting AES-GCM
decryptThese prevent maliciously large state parameters from causing excessive CPU or memory usage during decoding and decryption.
options(shinyOAuth.callback_max_code_bytes = 8192) –
maximum decoded byte length of the code callback parameter
across direct, GET/POST bridge, module and JARM paths. Explicit lower or
higher limits remain effective; values are rejected rather than
truncatedoptions(shinyOAuth.callback_max_state_bytes = 8192) –
maximum byte length of the state query parameter (outer
token string)options(shinyOAuth.callback_max_error_bytes = 256) –
maximum byte length of the error query parameteroptions(shinyOAuth.callback_max_error_description_bytes = 4096)
– maximum byte length of the error_description query
parameteroptions(shinyOAuth.callback_max_error_uri_bytes = 2048)
– maximum byte length of the error_uri query parameteroptions(shinyOAuth.callback_max_iss_bytes = 2048) –
maximum byte length of the iss query 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 the browser_token argument
accepted by handle_callback()options(shinyOAuth.callback_max_form_post_body_bytes = <derived>)
– maximum byte length of the raw form_post callback body
before parsingoptions(shinyOAuth.callback_max_form_post_handle_bytes = 128)
– maximum byte length of the transient shinyOAuth_form_post
handle query parameteroptions(shinyOAuth.callback_max_form_post_id_bytes = 256)
– maximum byte length of the transient
shinyOAuth_form_post_id module-id query parameterThese 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.
options(shinyOAuth.skip_browser_token = TRUE) – skip
browser cookie binding in tests or interactive sessions
options(shinyOAuth.skip_id_sig = TRUE) – skip ID
token signature verification in tests or interactive sessions
options(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 it
options(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.