# Secure SSO Token Handling in Coco App: The `handle_sso_callback` Strategy

> Learn how Coco App's handle_sso_callback strategy securely handles SSO tokens, preventing attacks with frontend validation and secure backend token storage in native storage.

- Repository: [INFINI Labs/coco-app](https://github.com/infinilabs/coco-app)
- Tags: technical-post
- Published: 2026-03-04

---

**Coco App mitigates OAuth interception and replay attacks by validating a one-time request ID in the frontend before delegating the authorization code exchange to the Tauri backend, where tokens are stored in native storage never accessible to the renderer process.**

The open-source Coco App (`infinilabs/coco-app`) implements a hardened OAuth 2.0 flow for single sign-on (SSO) that keeps access tokens out of the JavaScript runtime. By leveraging Tauri's multi-process architecture, the application ensures that securely handling SSO tokens after `handle_sso_callback` involves strict state validation, server-side token exchange, and filesystem-level isolation.

## CSRF Protection via One-Time Request IDs

### Generating the State Parameter in the UI

When a user initiates login, [`src/components/Cloud/ServiceAuth.tsx`](https://github.com/infinilabs/coco-app/blob/main/src/components/Cloud/ServiceAuth.tsx) generates a cryptographically random UUID to serve as a transient state parameter. This value is stored in the global `appStore` (`ssoRequestID`) and embedded in the authentication URL sent to the identity provider (IdP).

```tsx
// src/components/Cloud/ServiceAuth.tsx
const LoginClick = useCallback(() => {
  if (loading) return;

  const requestID = uuidv4();               // one-time UUID
  setSSORequestID(requestID);               // store in appStore

  const url = `${cloudSelectService?.auth_provider?.sso?.url}
               /?provider=${cloudSelectService?.id}
               &product=coco
               &request_id=${requestID}`;   // embed in SSO URL

  console.log("Open SSO link, requestID:", url);
  OpenURLWithBrowser(url);                  // open in external browser
  setLoading(true);
}, [loading, cloudSelectService]);

```

This pattern ensures that the authorization request is bound to a specific client state, preventing cross-site request forgery (CSRF) attacks where a malicious actor might attempt to inject a stolen authorization code.

### Deep-Link Validation Before Backend Invocation

The [`useDeepLinkManager.ts`](https://github.com/infinilabs/coco-app/blob/main/useDeepLinkManager.ts) hook intercepts the OAuth callback via the operating system's deep-link handler. Before calling the Tauri backend, it extracts both the `request_id` and `code` from the callback URL and performs a strict equality check against the value held in `appStore`.

```tsx
// src/hooks/useDeepLinkManager.ts
const handleOAuthCallback = useCallback(async (url: URL) => {
  const reqId = url.searchParams.get("request_id");
  const code  = url.searchParams.get("code");

  const { ssoRequestID } = useAppStore.getState();   // retrieve stored state
  if (reqId !== ssoRequestID) {
    addError("Request ID not matched, skip");
    return;                                          // abort if mismatch
  }

  const serverId = cloudSelectService?.id;
  if (!code || !serverId) return;

  // delegate to backend (only code, no token)
  await platformAdapter.commands("handle_sso_callback", {
    serverId,
    requestId: ssoRequestID,
    code,
  });

  platformAdapter.emitEvent("oauth_success", { serverId });
}, []);

```

If the received `request_id` does not match the stored `ssoRequestID`, the flow aborts immediately, shielding the backend from processing potentially replayed or malicious authentication attempts.

## Backend Token Isolation and Persistence

### The `handle_sso_callback` Command Implementation

Located in [`src-tauri/src/server/auth.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/server/auth.rs), the `handle_sso_callback` command receives only the `server_id`, `request_id`, and `code`. It never accepts a pre-fetched token, ensuring that the frontend cannot inject arbitrary bearer tokens. The function exchanges the authorization code for an access token via the Coco-Server API and immediatelymaterializes a `ServerAccessToken` instance.

```rust
// src-tauri/src/server/auth.rs
#[tauri::command]
pub async fn handle_sso_callback(
    app_handle: AppHandle,
    server_id: String,
    request_id: String,
    code: String,
) -> Result<(), String> {
    // exchange code → access token (performed by the server)
    let access_token = ServerAccessToken::new(server_id.clone(), code.clone(), 3600);
    save_access_token(server_id.clone(), access_token).await; // store securely
    persist_servers_token(&app_handle).await?;               // persist to disk

    // additional profile refresh omitted for brevity
    Ok(())
}

```

According to the Coco App source code, the `save_access_token` function stores the token in a memory-safe structure, while `persist_servers_token` (defined in [`src-tauri/src/server/servers.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/server/servers.rs)) serializes the data to the Tauri data directory—outside the Chromium WebView sandbox.

### Native Storage Outside the Renderer

The `persist_servers_token` utility writes the token store to the local filesystem using Tauri's native APIs. This architecture guarantees that:

- **Token confidentiality**: The access token is handled exclusively within the Rust backend; the string never traverses the IPC boundary to the TypeScript frontend.
- **Secure persistence**: Tokens reside in the operating system's user data directory, protected by OS-level file permissions, rather than `localStorage` or `IndexedDB` where they could be accessed by XSS payloads.

## Event-Driven UI Synchronization

Rather than returning the token to the frontend, the backend signals completion by emitting an `oauth_success` event. The `ServiceAuth` component subscribes to this event via `platformAdapter.listenEvent` and refreshes the server metadata without ever handling the raw bearer token.

```tsx
// src/components/Cloud/ServiceAuth.tsx
const { run: debouncedAuthSuccess } = useDebounceFn((event) => {
  const { serverId } = event.payload;
  if (serverId) {
    refreshClick(serverId, () => setLoading(false));
    addError(t("cloud.connect.hints.loginSuccess"), "info");
  }
});

useEffect(() => {
  const unlistenOAuth = platformAdapter.listenEvent(
    "oauth_success",
    debouncedAuthSuccess
  );
  return () => { unlistenOAuth.then(fn => fn()); };
}, [refreshClick]);

```

This event-driven model enforces **least-privilege UI design**: the renderer process learns only that authentication succeeded, while the sensitive credential remains confined to the native backend.

## Summary

- **State validation**: A one-time UUID generated in [`ServiceAuth.tsx`](https://github.com/infinilabs/coco-app/blob/main/ServiceAuth.tsx) and verified in [`useDeepLinkManager.ts`](https://github.com/infinilabs/coco-app/blob/main/useDeepLinkManager.ts) prevents CSRF and replay attacks by rejecting callbacks with mismatched `request_id` values.
- **Backend isolation**: The `handle_sso_callback` command in [`src-tauri/src/server/auth.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/server/auth.rs) performs the OAuth token exchange, ensuring the access token is never exposed to the JavaScript context.
- **Native persistence**: The `persist_servers_token` function stores credentials in the Tauri data directory, isolated from the WebView sandbox and XSS vulnerabilities.
- **Event architecture**: The UI receives only an `oauth_success` signal, maintaining strict separation between the authentication state and the token material.

## Frequently Asked Questions

### How does Coco App prevent CSRF attacks during SSO?

Coco App prevents CSRF attacks by generating a cryptographically random UUID (`requestID`) when the user clicks **Login**, storing it in the global `appStore`, and appending it to the SSO URL as a state parameter. When the IdP redirects back to the app, [`useDeepLinkManager.ts`](https://github.com/infinilabs/coco-app/blob/main/useDeepLinkManager.ts) validates that the callback's `request_id` matches the stored value before invoking `handle_sso_callback`; any mismatch aborts the flow immediately.

### Where are access tokens stored after `handle_sso_callback`?

Access tokens are stored exclusively in the Tauri backend's native filesystem via the `persist_servers_token` function in [`src-tauri/src/server/servers.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/server/servers.rs). This writes the `ServerAccessToken` data to the Tauri data directory (e.g., `$APP_DATA` on Linux/macOS or `%APPDATA%` on Windows), ensuring the token persists across sessions without ever entering the browser's storage mechanisms.

### Why doesn't the frontend receive the raw access token?

The frontend does not receive the raw access token to enforce the **principle of least privilege** and mitigate XSS risks. The `handle_sso_callback` command in [`src-tauri/src/server/auth.rs`](https://github.com/infinilabs/coco-app/blob/main/src-tauri/src/server/auth.rs) performs the code exchange and persists the token internally, then emits an `oauth_success` event to notify the UI of completion. This design ensures that even if the renderer process is compromised, the attacker cannot extract the bearer token from memory or storage.

### What happens if the `request_id` does not match during callback?

If the `request_id` parameter in the OAuth callback URL does not match the `ssoRequestID` stored in `appStore`, the `handleOAuthCallback` function in [`src/hooks/useDeepLinkManager.ts`](https://github.com/infinilabs/coco-app/blob/main/src/hooks/useDeepLinkManager.ts) logs an error ("Request ID not matched, skip") and returns early without calling the Tauri backend. This prevents the application from exchanging a potentially stolen authorization code, effectively blocking replay attacks and unauthorized authentications.