Authentication & Authorization
Authentication & Authorization is the security foundation of RTC Agent. Users log in via the OAuth2 authorization code flow, and the system maintains sessions using dual tokens (Access + Refresh). It supports parallel multi-device logins and automatic token refresh — users only need to sign in once for long-term use.
Login Flow
Section titled “Login Flow”| Step | Description |
|---|---|
| 1 | User clicks the login button, and a login dialog appears |
| 2 | The dialog displays the OAuth2 Provider’s authorization page via an iframe |
| 3 | User completes authorization on the Provider page (e.g., GitHub, Google) |
| 4 | After successful authorization, the system obtains the authorization code and exchanges it for tokens |
| 5 | Tokens are stored in the browser locally, and login is complete |
💡 Design Principle: The login flow is fully delegated to the OAuth2 Provider — RTC Agent never handles user passwords; security is guaranteed by the Provider.
Dual-Token Mechanism
Section titled “Dual-Token Mechanism”| Token | Validity | Purpose | Storage |
|---|---|---|---|
| 🔑 Access Token | 1 hour | Access API and WebSocket | Plaintext (short validity, manageable risk) |
| 🔄 Refresh Token | 30 days | Refresh Access Token | Hash only (plaintext returned once at issuance, then discarded) |
📌 Security Key Point: The Refresh Token’s plaintext is only returned once at issuance; afterward, the server stores only the hash. Even if browser storage is compromised, attackers cannot impersonate the user long-term.
Automatic Refresh
Section titled “Automatic Refresh”The system automatically refreshes tokens at multiple trigger points, completely transparent to the user:
| Trigger | Description |
|---|---|
| ⏱️ Token about to expire | Automatically refreshed 5 minutes before expiration to avoid request interruption |
| 📱 Page returns to foreground | Token status is checked when switching back from background; refresh immediately if expired |
| 🔌 Establishing WebSocket | Refresh token on demand during connection to ensure validity |
💡 Refresh failures don’t leave users in a “half-dead” state — the system logs them out directly and guides them to re-authenticate.
Device Management
Section titled “Device Management”| Concept | Description |
|---|---|
| 🔖 Device ID | Unique browser identifier (UUID), automatically generated on first visit |
| 📛 Device Name | Automatically inferred from OS (e.g., “Mac”, “Windows PC”, “Linux PC”) |
| 🔀 Multi-device | The same user can log in independently on multiple devices without interference |
📌 Tokens are independent per device — logging out on Device A does not affect the session on Device B.
WebSocket Authentication
Section titled “WebSocket Authentication”| Phase | Description |
|---|---|
| 🔗 Connect | WebSocket connection carries the Access Token for authentication |
| ✅ Verify | Server validates token validity; invalid tokens are rejected |
| 📡 Subscribe | After authentication, subscribe to the user-specific channel to receive real-time messages |
| 🔁 Disconnect | Reconnection requires re-authentication to ensure security |
💡 Channel Isolation: Each user can only receive messages from their own channel and cannot access other users’ data.
Security Constraints
Section titled “Security Constraints”| Constraint | Mechanism | Purpose |
|---|---|---|
| 🛡️ CSRF Protection | Use state parameter during OAuth2 authorization | Prevent cross-site request forgery attacks |
| 🏷️ Channel Isolation | Users can only subscribe to their own dedicated channel | Prevent data leaks and unauthorized access |
| 💾 Token Storage | Tokens stored only in browser locally | Not sent to third parties, reducing leak risk |
| 🔑 Refresh Token | Plaintext returned once; server stores hash only | Cannot be used long-term even if storage is compromised |
Error Handling
Section titled “Error Handling”| Scenario | User-facing behavior |
|---|---|
| ❌ Authorization failed | Login dialog shows error message; retry is available |
| ⏱️ Token expired and refresh failed | Automatically logged out; login page displayed |
| 🔌 WebSocket authentication failed | Connection disconnected; user prompted to log in again |
Next Steps
Section titled “Next Steps”- Web Component API — Learn how to integrate RTC Agent via the
<rtc-agent>component - Function Registration Guide — Register custom functions to extend AI capabilities
- Core Protocol RTC — Learn about the full lifecycle of Remote Tool Calling
Developer Integration Guide
Section titled “Developer Integration Guide”RTC Agent Server is an OAuth2 consumer — it needs to connect to an OAuth2 provider to authenticate users. The development environment includes a built-in mock-oauth2 as a sample provider; for production deployments, you need to provide your own OAuth2 service.
Architecture
Section titled “Architecture”RTC Agent Server handles JWT issuance and device management; your OAuth2 service is only responsible for verifying user identity and returning user information.
Endpoints to Implement
Section titled “Endpoints to Implement”Your OAuth2 service only needs to implement 2 endpoints:
Endpoint 1: Authorization Page — GET /oauth2/authorize
Section titled “Endpoint 1: Authorization Page — GET /oauth2/authorize”Accessed directly by the browser (loaded via iframe), used to display the login/authorization UI.
Request (assembled by RTC Agent Server, accessed by the browser):
GET /oauth2/authorize?state=<hex>&client_id=<id>&redirect_uri=<uri>| Parameter | Description |
|---|---|
state | Anti-CSRF random string, must be echoed back as-is |
client_id | Client identifier |
redirect_uri | Callback URL after successful authorization |
Behavior requirements:
- Display a login/authorization page (can be your existing login system)
- After user authorizes, generate a short-lived, single-use authorization code
- HTTP 302 redirect to
redirect_uriwithcodeandstatein the query string:
Location: <redirect_uri>?code=<code>&state=<state>Page constraints:
- The page will be loaded in an iframe — you must not set
X-Frame-Options: DENYor a restrictiveContent-Security-Policy: frame-ancestors - Content-Type must be
text/html; charset=utf-8
Endpoint 2: Code Exchange — POST /oauth2/token/exchange
Section titled “Endpoint 2: Code Exchange — POST /oauth2/token/exchange”Called server-to-server directly by RTC Agent Server, exchanging the authorization code for user identity.
Request:
POST /oauth2/token/exchangeContent-Type: application/x-www-form-urlencodedAccept: application/json
client_id=<id>&client_secret=<secret>&code=<code>&redirect_uri=<uri>Success response (200):
{ "provider_user_id": "user-12345", "username": "John Doe", "email": "john@example.com", "avatar_url": "https://example.com/avatar.png"}| Field | Required | Description |
|---|---|---|
provider_user_id | ✅ | Stable unique identifier for the user in your system — must be the same value for the same user every time |
username | Optional | Display name |
email | Optional | Email address |
avatar_url | Optional | Avatar URL |
Error responses:
{ "error": "invalid_client", "error_description": "Invalid client_id or client_secret"}| HTTP Status | error value | Meaning |
|---|---|---|
| 400 | invalid_request | Missing or invalid parameters |
| 400 | invalid_grant | Authorization code is invalid, already used, or expired |
| 401 | invalid_client | Invalid client credentials |
| 500 | server_error | Internal server error |
Authorization Code Semantics
Section titled “Authorization Code Semantics”| Constraint | Description |
|---|---|
| Single-use | The same code can only be exchanged once |
| Short-lived | Recommend expiry within 10 minutes |
| User-bound | The code must be associated with the authenticated user’s identity |
What You Don’t Need to Implement
Section titled “What You Don’t Need to Implement”- ❌ No need to issue access_token / refresh_token — RTC Agent Server issues JWTs itself
- ❌ No need to implement a standard OAuth2
/tokenendpoint —/oauth2/token/exchangeis essentially a user info endpoint - ❌ No need to support scope, PKCE, or other extensions
Configure RTC Agent Server
Section titled “Configure RTC Agent Server”After implementing your OAuth2 service, point the Server config to it:
providers: mock: enabled: true url: "https://your-oauth-server.com" # Your OAuth2 service address client_id: "your-client-id" # client_id agreed with your service client_secret: "your-client-secret" # client_secret agreed with your service⚠️ The
mockinproviders.mockis the provider name (it doesn’t mean “test only”). The Server will concatenate{url}/oauth2/authorizeand{url}/oauth2/token/exchangeas the two endpoint addresses. If your service uses different paths, you’ll need to extendBuildProviderClientsor keep the paths consistent.