# How holaOS Handles User Authentication and Authorization: OAuth 2.0 Architecture Explained

> Discover how holaOS handles user authentication and authorization using a centralized OAuth 2.0 architecture. Learn about its three-layer model for secure and efficient access management.

- Repository: [holaboss.ai/holaOS](https://github.com/holaboss-ai/holaOS)
- Tags: architecture
- Published: 2026-08-15

---

**holaOS implements a centralized OAuth 2.0-based authentication model with three-layer architecture: provider configuration storage, authorization flow management, and runtime token enforcement that automatically prompts users for re-authorization when tokens expire.**

The open-source holaOS project (holaboss-ai/holaOS) provides a secure, extensible framework for managing third-party service access. Its authentication and authorization系统设计 prioritizes **user control**, **token isolation**, and **seamless UI integration**—ensuring every request to integrated services carries a fresh, user-approved credential.

---

## Three-Layer Authentication Architecture

holaOS structures its authentication and authorization system into distinct layers that operate from configuration through runtime enforcement.

### 1. OAuth Configuration Storage Layer

All third-party authentication providers are defined in [`runtime/state-store/src/store.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/state-store/src/store.ts). The schema separates **provider definitions** from **user-specific connections**:

- **`oauth_app_configs`** table stores provider metadata: `authorize_url`, `token_url`, `scope`, `client_id`, and `client_secret`
- **`integration_connections`** table links users and workspaces to providers, tracking `auth_mode`, `granted_scopes`, and a `secret_ref` pointer to the actual token

This design enables **provider-agnostic OAuth definition**—adding a new service requires only inserting a configuration row without code changes.

### 2. Authorization Flow Layer (OAuth 2.0)

The flow implementation in [`runtime/api-server/src/oauth-service.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/api-server/src/oauth-service.ts) handles the complete handshake:

- **`startFlow(providerId, ownerUserId)`**: Constructs the authorization URL with PKCE parameters and returns it to the frontend
- **Callback endpoint** (`/api/v1/integrations/oauth/callback`): Exchanges the authorization code for tokens and persists the connection record

```typescript
// Starting an OAuth flow from the client
const resp = await fetch('/api/v1/integrations/oauth/authorize', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ providerId: 'google', ownerUserId: user.id })
});
const { authorize_url } = await resp.json();
window.open(authorize_url, '_blank');

```

*Source:* [`runtime/api-server/src/app.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/api-server/src/app.ts) — POST handler delegates to `OAuthService.startFlow` at line 5618

### 3. Runtime Enforcement Layer

Three mechanisms ensure tokens remain valid and requests are properly authorized:

**MCP Server Authorization**

[`runtime/harness-host/src/mcp-authorize.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/harness-host/src/mcp-authorize.ts) executes the `authorize-mcp` sub-command, storing tokens in a **per-workspace secure cache** (`mcp-oauth/` directory) rather than the main database. This isolates secrets and enables workspace-scoped token rotation.

**API Gatekeeper Middleware**

[`runtime/api-server/src/app.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/api-server/src/app.ts) contains middleware that validates inbound requests:

```typescript
function requireAuth(req: Request, res: Response, next: NextFunction) {
  const authHeader = req.headers['authorization'];
  if (!authHeader) return sendError(res, 401, 'unauthorized');
  const token = tokenCache.get(authHeader.split(' ')[1]);
  if (!token) return sendError(res, 401, 'unauthorized');
  next();
}

```

Missing or invalid tokens trigger **401 Unauthorized** responses. Connections in `needs_reauth` state receive the same treatment, forcing re-authentication.

**Automatic Re-Authorization**

When tools detect expired credentials, [`runtime/harnesses/src/runtime-agent-tools.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/harnesses/src/runtime-agent-tools.ts) exposes the `mcp_reauthorize` tool:

```typescript
{
  id: 'mcp_reauthorize',
  description: 'Re-run the OAuth sign-in for an already-connected remote MCP server.',
  args: [{ name: 'server', type: 'string' }],
  handler: async ({ server }) => {
    // Returns UI card with re-authorize button triggering authorizeMcpServer(server, { reauthorize: true })
  }
}

```

This surfaces an inline **Re-authorize** button that launches a fresh OAuth flow without creating duplicate integration records.

---

## Token Storage Security Model

holaOS employs a **reference-based token architecture** that keeps sensitive credentials out of the database:

| Component | Location | Purpose |
|-----------|----------|---------|
| Token metadata | `integration_connections` table | Links user/workspace to provider, tracks status |
| Actual tokens | On-disk cache (`mcp-oauth/`) | Cryptographically isolated, workspace-scoped |
| Reference pointer | `secret_ref` field in record | Enables token rotation without DB migration |

This separation means a database compromise does not expose live OAuth tokens—a critical defense-in-depth measure for authentication and authorization systems.

---

## Handling Expired Credentials

The runtime gracefully manages token expiration through state transitions:

1. **Detection**: [`runtime/harnesses/src/mcp.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/harnesses/src/mcp.ts) intercepts 401/403 responses and sets `authRequired` flag
2. **State marking**: Connection status changes to `needs_reauth` in `integration_connections`
3. **UI triggering**: Next tool invocation automatically renders the authorization prompt
4. **Recovery**: User clicks through OAuth flow, new token replaces cached entry via `authorize-mcp`

This **automatic UI prompting** eliminates manual token management while maintaining security boundaries.

---

## Key Implementation Files

| File Path | Responsibility |
|-----------|--------------|
| [`runtime/state-store/src/store.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/state-store/src/store.ts) | SQLite schema for OAuth configs and user connections |
| [`runtime/api-server/src/oauth-service.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/api-server/src/oauth-service.ts) | OAuth flow initiation and token exchange |
| [`runtime/api-server/src/app.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/api-server/src/app.ts) | Authorization endpoints and 401 enforcement middleware |
| [`runtime/harness-host/src/mcp-authorize.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/harness-host/src/mcp-authorize.ts) | MCP server token acquisition and cache management |
| [`runtime/harnesses/src/runtime-agent-tools.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/harnesses/src/runtime-agent-tools.ts) | `mcp_reauthorize` tool for credential refresh |
| [`runtime/harnesses/src/mcp.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/harnesses/src/mcp.ts) | Authentication failure detection and state management |

---

## Summary

- **holaOS authentication and authorization** centers on OAuth 2.0 with provider-agnostic configuration storage
- **Three-layer architecture** separates concerns: configuration, flow orchestration, and runtime enforcement
- **Token isolation** via on-disk cache with database references protects against credential leaks
- **Automatic re-authorization** flows keep user experience seamless without sacrificing security
- **MCP-specific tooling** enables LLM agents to request credential refreshes through structured UI interactions

---

## Frequently Asked Questions

### How does holaOS store OAuth tokens securely?

Tokens are never stored in the main database. Instead, [`runtime/harness-host/src/mcp-authorize.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/harness-host/src/mcp-authorize.ts) writes them to a **per-workspace secure cache** on disk, while `integration_connections` holds only a `secret_ref` pointer. This design isolates secrets from SQL queries and enables granular token rotation.

### What happens when a third-party token expires?

The MCP harness detects 401/403 responses and marks the connection `needs_reauth`. The next time the tool is invoked, [`runtime/harnesses/src/runtime-agent-tools.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/harnesses/src/runtime-agent-tools.ts) surfaces a **Re-authorize** button that triggers `authorizeMcpServer(server, { reauthorize: true })`—reusing the existing integration record rather than creating a new one.

### Can holaOS support custom OAuth providers?

Yes. Adding a provider requires only inserting a row into `oauth_app_configs` with `authorize_url`, `token_url`, `scope`, and credentials. The `startFlow()` method in [`runtime/api-server/src/oauth-service.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/api-server/src/oauth-service.ts) dynamically constructs URLs from this configuration, requiring no code changes for new providers.

### How does the API server reject unauthorized requests?

Middleware in [`runtime/api-server/src/app.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/api-server/src/app.ts) validates the `Authorization` header against the token cache. Missing headers, invalid tokens, or connections in `needs_reauth` state all return **401 Unauthorized**. The same middleware handles the `/api/v1/integrations/oauth/authorize` endpoint for initiating new flows.