MCPcopy Create free account
hub / github.com/NVIDIA/OpenShell / _OidcRefresher

Class _OidcRefresher

python/openshell/sandbox.py:932–1313  ·  view source on GitHub ↗

Thread-safe in-process OAuth2 refresh for a gateway's `oidc_token.json`. Mirrors the lazy-refresh pattern used by `google-auth`'s `Credentials` and `botocore`'s `SSOTokenProvider`. Uses `httpx` for transport so we can pin `follow_redirects=False` and the TLS verification policy expl

Source from the content-addressed store, hash-verified

930
931
932class _OidcRefresher:
933 """Thread-safe in-process OAuth2 refresh for a gateway's `oidc_token.json`.
934
935 Mirrors the lazy-refresh pattern used by `google-auth`'s `Credentials`
936 and `botocore`'s `SSOTokenProvider`. Uses `httpx` for transport so
937 we can pin `follow_redirects=False` and the TLS verification policy
938 explicitly — same posture as the Rust CLI's use of `reqwest` with
939 `Policy::none()` and an opt-in `danger_accept_invalid_certs` (see
940 `crates/openshell-cli/src/oidc_auth.rs::http_client`). The OAuth2
941 refresh-token grant itself (RFC 6749 §6) is a single form-encoded
942 POST, handled inline rather than via an OAuth2 library.
943
944 Properties:
945
946 - **Lazy**: check expiry on every RPC; refresh only when stale.
947 - **Lock-coordinated**: concurrent RPCs share a single refresh, not
948 one per call. Plain `threading.Lock` (no separate worker thread,
949 unlike `google-auth`'s `RefreshThreadManager` — sufficient for
950 our use case).
951 - **Disk-aware**: before refreshing, re-read `oidc_token.json` —
952 the CLI or another process may have already rotated the bundle.
953 - **Discovery-validated**: fetches the OIDC discovery document
954 from `<issuer>/.well-known/openid-configuration`, rejects
955 responses whose `issuer` field doesn&#x27;t match the configured one
956 (preventing SSRF / misdirection of the refresh_token to an
957 attacker-controlled endpoint). Mirrors the Rust CLI&#x27;s
958 `discover()` function.
959 - **Redirect-hardened**: `follow_redirects=False` on the underlying
960 `httpx.Client` so a 3xx during discovery or refresh is treated
961 as a failure rather than silently chasing the redirect to an
962 arbitrary host.
963 - **Write-back by default**: when `auto_refresh=True`, refreshed
964 bundles are atomically persisted to `oidc_token.json` at mode
965 0600 so other processes (Rust CLI, TUI, other Python clients)
966 see the rotated `refresh_token`. Required for IdPs that
967 invalidate the old `refresh_token` on rotation (Keycloak with
968 rotation enabled, Entra in strict mode); without write-back, a
969 second process would `invalid_grant` on next refresh.
970 - **`insecure=True` flag** disables TLS certificate verification
971 for the discovery and refresh calls. Matches the Rust CLI&#x27;s
972 `--insecure` plumbing for OIDC issuers behind self-signed certs.
973 - **Refresh failures** surface as `SandboxError` with a
974 "re-authenticate with: openshell gateway login" hint.
975 """
976
977 def __init__(
978 self,
979 gateway_dir: pathlib.Path,
980 cluster_name: str,
981 *,
982 write_back: bool = True,
983 insecure: bool = False,
984 ) -> None:
985 self._gateway_dir = gateway_dir
986 self._cluster_name = cluster_name
987 self._write_back = write_back
988 self._lock = threading.Lock()
989 self._bundle: dict | None = None

Calls

no outgoing calls