# Authentication and access

Use browser sessions, management credentials, and instance capabilities in their intended contexts.

Source: https://docs.minds.sh/docs/api/platform/authentication



A request needs both a recognized identity and permission to act on the requested organization or Mind. Supplying an organization ID is not proof that the caller can use it.

## Signed-in browser requests [#signed-in-browser-requests]

Most dashboard routes call `getSession()` from the shared authentication package. It reads the HTTP-only `l1fe_access_token` cookie and verifies the JWT against the configured sign-in service, issuer, and audience. Browser code should make same-origin requests and let the browser send the cookie.

```typescript
const response = await fetch('/api/chat/context', {
  credentials: 'same-origin',
  cache: 'no-store',
});
if (response.status === 401) {
  // Return the user to the application's sign-in flow.
}
```

The OAuth exchange endpoint accepts `code`, `redirect_uri`, and `code_verifier`. The server exchanges them with the configured sign-in provider and sets authentication cookies. The response reports authentication state and expiry; it does not return the refresh token. Refresh and logout are separate POST operations. Use the application's sign-in flow rather than implementing a second cookie format.

| Endpoint                    | Purpose                                                                                                           |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `GET /api/auth/session`     | Check the session through the upstream user-info service; returns authentication state and a limited user profile |
| `GET /api/auth/get-session` | Return the shared session object: user, access token, and expiry, or `null`                                       |
| `GET /api/auth/token`       | Deliberate access-token bridge for browser integrations that need it                                              |
| `POST /api/auth/exchange`   | Complete the authorization-code exchange and set cookies                                                          |
| `POST /api/auth/refresh`    | Refresh authentication using the refresh cookie                                                                   |
| `POST /api/auth/logout`     | Revoke where possible, clear local authentication cookies, and return the sign-out URL                            |

Treat the token and full-session responses as credentials. Do not include them in logs, screenshots, analytics, or URLs. An access-token bridge does not make refresh tokens available to browser JavaScript.

Some older dashboard routes use `auth()` and redirect to sign-in rather than returning JSON 401. Read the endpoint's documented branches before assuming all failures have the same body.

## Management API keys and sessions [#management-api-keys-and-sessions]

The management service's `resolveAuthContext()&#x60; accepts configured session authentication and validates a legacy API key from the **`x-api-key` header**. An invalid key is an authentication failure. The trusted-gateway integration can also resolve a caller through its configured authentication pipeline.

Do not forge `x-consumer-*` gateway headers from a customer application. Their meaning depends on the trusted gateway and deployment configuration.

```bash
curl --fail-with-body \
  --header "x-api-key: $MINDS_MANAGEMENT_API_KEY" \
  "$MINDS_MANAGEMENT_URL/api/v1/tenants/$MINDS_TENANT_ID/status"
```

`requireOrgAccess()` and `ensureTenantAccess()` apply organization membership, tenant ownership, API-key scope, or the configured policy decision. A recognized credential can still receive 403 for a different organization.

Several SDKs call their constructor field `api_key` or `APIKey` but send it as `Authorization: Bearer ...`. That is not the same as this legacy `x-api-key` route. See [SDK compatibility](/docs/developers/compatibility) before selecting a client.

## Dedicated instance capabilities [#dedicated-instance-capabilities]

The dashboard's Akasha proxy resolves the signed-in user's active organization and authorized service, then creates an upstream capability scoped to the operation and memory keyspaces. It sends that credential as `x-akasha-capability` with organization, tenant, and service identifiers.

Direct instance integrations need an instance credential accepted by that deployment. A caller cannot gain another tenant's namespace by adding a JSON `namespace` field or arbitrary `X-Akasha-*` headers. For MCP HTTP tool calls, the daemon derives authority from the verified request credential.

The management service also exposes `POST /api/v1/tenants/[id]/tokens`. Its `GenerateTokenRequest` and issued token format are in [the endpoint contract](/docs/api/platform/reference/management--api-v1-tenants-id-tokens). Do not assume that a token issued by an older management deployment is interchangeable with the capability policy of a newer dedicated daemon.

## Authentication evidence [#authentication-evidence]

Source: `minds-ui/packages/auth/server.ts`, `minds-ui/apps/api-service/lib/services/auth-context.ts`, `minds-ui/apps/api-service/lib/auth/session.ts`, and `minds-ui/apps/app/app/api/akasha/proxy.ts`. This describes current source behavior; each deployment must configure its trusted issuer, gateway, and capability verifier.
