> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hookfish.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Application authentication

> Authenticate users in your application, then call Hookfish from trusted server code with Hono RPC.

Hookfish does not authenticate your users. Keep Auth.js, Clerk, Auth0,
Supabase Auth, or your existing session system in your application. After your
application authorizes a request, call Hookfish from the server with a scoped
broker credential.

```text theme={null}
Browser
  → your application API
  → session authentication and permission checks
  → server-side Hono RPC client
  → Hookfish /api
```

This keeps application sessions out of Hookfish and broker credentials out of
the browser.

## Protect an application route

Use your auth provider's server middleware before the route handler. Retain the
user and tenant identifiers your authorization policy needs.

```ts theme={null}
import { Hono } from 'hono'
import { createMiddleware } from 'hono/factory'

type AuthVariables = {
  user: {
    id: string
    organizationId: string
  }
}

const requireUser = createMiddleware<{ Variables: AuthVariables }>(
  async (context, next) => {
    const user = await authenticateRequest(context.req.raw)

    if (!user) {
      return context.json({ error: 'Sign in required.' }, 401)
    }

    context.set('user', user)
    await next()
  },
)

const app = new Hono<{ Variables: AuthVariables }>()

app.use('/integrations/*', requireUser)
```

Keep provider-specific session verification inside `authenticateRequest`. Test
signed-in, signed-out, expired-session, and wrong-tenant cases.

| Application auth provider | Server-side check                                | Identity to retain              |
| ------------------------- | ------------------------------------------------ | ------------------------------- |
| Auth.js                   | Resolve and validate the current server session  | User and tenant IDs             |
| Clerk                     | Verify the request and resolve its auth context  | User and organization IDs       |
| Auth0                     | Validate the application session or access token | Subject and organization claim  |
| Supabase Auth             | Resolve the user from a server client            | User and application tenant IDs |

## Call Hookfish after authorization

Create the Hookfish Hono RPC client inside trusted server code. Select a broker
token whose resource scope matches the current user or organization.

```ts theme={null}
import type { AppType as HookfishAppType } from '@hookfish/api'
import { hc } from 'hono/client'

const hookfishUrl =
  process.env.HOOKFISH_URL ?? 'http://127.0.0.1:8787'

function hookfishFor(brokerToken: string) {
  return hc<HookfishAppType>(`${hookfishUrl}/api`, {
    headers: {
      Authorization: `Bearer ${brokerToken}`,
    },
  })
}

app.get('/integrations/connections', async (context) => {
  const user = context.get('user')
  const brokerToken = await scopedBrokerTokenFor(user.organizationId)
  const hookfish = hookfishFor(brokerToken)

  const response = await hookfish.oauth.connections.$get({
    query: {
      connection_id_prefix: user.organizationId,
    },
  })

  if (!response.ok) {
    return context.json({ error: 'Could not load connections.' }, 502)
  }

  return context.json(await response.json())
})
```

Use the same pattern to start authorization, disconnect an account, retrieve a
provider token, or access a vault secret. Return only the data the browser
needs. Provider tokens and decrypted secrets should remain in server code.

## Expose your application API to the browser

Export your application route type and create a separate Hono RPC client in
the browser. That client sends the user's normal application session. It does
not send a Hookfish credential.

```ts theme={null}
// server.ts
export type ApplicationApi = typeof app
```

```ts theme={null}
// browser.ts
import type { ApplicationApi } from './server'
import { hc } from 'hono/client'

export const api = hc<ApplicationApi>('/api', {
  init: {
    credentials: 'include',
  },
})
```

<Warning>
  Never return a root key or scoped broker token to the browser. Application
  authentication does not replace Hookfish resource scopes; enforce both.
</Warning>
