Verified: 3-legged OAuth supported
RISEDUAL AI fully supports 3-legged OAuth 2.0 for Charles Schwab integration.
This page is a human-readable companion to our machine-verifiable endpoint at /api/broker/oauth/capabilities. Third-party broker review teams may link either resource as proof of compliance. Last reviewed: August 29, 2026.
OAuth 2.0 Capability Matrix
Live-pulled from the app backend on this page load.
3-legged OAuth (Authorization Code Grant)Supported
PKCE (S256 code challenge)Supported
CSRF state validation (one-time tokens)Supported
Refresh-token rotation on every refreshSupported
Token storage encrypted (AES-256 (Fernet))Supported
Charles Schwab Endpoint Configuration
- Broker ID
- schwab
- PKCE Enabled
- Yes (S256)
- Authorize URL
- https://api.schwabapi.com/v1/oauth/authorize
- Token Expiry Honored
- 1800s (30 min)
- Auto-Refresh
- At 80% of expiry
- Callback / Redirect URI pattern
- https://{production-domain}/api/broker/oauth/schwab/callback
Security Implementation Detail
- CSRF state tokens (one-time use)
- PKCE S256 code challenge for supported brokers
- Refresh token rotation on every refresh
- Token audit trail (oauth_token_audit collection)
- Encrypted credential storage (AES-256)
- Automatic token refresh at 80% expiry
- httpOnly secure cookies for session auth
Flow Summary
- User initiates connection. Frontend calls
GET /api/broker/oauth/schwab/authorize. Backend generates a CSRFstate, PKCE verifier+challenge (when supported), persists them server-side, and returns the Charles Schwab authorize URL. - User consents at Charles Schwab. Browser navigates to the broker's authorize endpoint. User authenticates and grants the requested scopes.
- Charles Schwab redirects back. Browser lands on
/api/broker/oauth/schwab/callback?code=…&state=…. Backend validatesstate, exchanges the code (plus PKCE verifier when applicable) for access+refresh tokens, encrypts them with AES-256 (Fernet) before storage, and redirects the user back to the app with a success flag. - Ongoing refresh. At 80% of token expiry, the backend auto-refreshes using the stored refresh token. Every rotation issues a new refresh token (rotation policy) and is logged to
oauth_token_audit.
For Reviewers
To machine-verify the claims on this page, GET the public endpoint below. It returns the same capability data this page renders, without authentication:
curl https://risedual.ai/api/broker/oauth/capabilities