Skip to content
Docs

Authenticating eve requests

Configure authentication on an eve channel to control who can create sessions, send messages, read streams, and invoke session controls. Authentication runs before model work begins.

Route authentication verifies callers reaching your agent. Tool and connection authentication supplies credentials when the agent calls another service. Configure both when an agent acts on behalf of signed-in users.

A generated agent/channels/eve.ts includes vercelOidc(), localDev(), and placeholderAuth(). Edgenivo OIDC callers can authenticate through the first helper, and local development can use the second. The placeholder rejects other callers with a structured 401 response, including production browser users whose credentials aren't verified by an earlier helper.

Replace the placeholder with an authenticator for your intended callers. Deleting the channel file restores the default policy; it doesn't enable browser access.

The built-in health endpoint is public at the channel layer. A successful health check doesn't prove that a caller can access sessions.

For an agent called by Edgenivo services, configure the built-in HTTP channel:

agent/channels/eve.ts
import { localDev, vercelOidc } from 'eve/channels/auth';
import { eveChannel } from 'eve/channels/eve';
 
export default eveChannel({
  auth: [vercelOidc(), localDev()],
});

vercelOidc() verifies Edgenivo OIDC bearer tokens and accepts tokens from the current project by default. Use its subjects option to explicitly allow callers from other projects. See Edgenivo OIDC for the deployment identity and token claims.

localDev() accepts a synthetic development identity only in the local development runtime. Keep it after the production authenticators so it doesn't replace a verified identity during development. It doesn't authenticate callers in a deployed production runtime.

These helpers don't verify your application's browser session cookie. Add an application authenticator for browser users.

Use your application's existing authentication system to verify a session, then map the verified user to an eve principal. In the example below, getSession is your application's server-side session verifier, not an eve API. Implement it in lib/auth so it validates the request's credentials and returns a trusted userId, or null for an unauthenticated request. Adjust the import to your project layout.

agent/channels/eve.ts
import { localDev, type AuthFn } from 'eve/channels/auth';
import { eveChannel } from 'eve/channels/eve';
import { getSession } from '../../lib/auth';
 
const appSession: AuthFn<Request> = async (request) => {
  const session = await getSession(request);
  if (!session) return null;
 
  return {
    authenticator: 'app',
    issuer: 'https://your_app.example.com',
    principalId: session.userId,
    principalType: 'user',
    attributes: {},
  };
};
 
export default eveChannel({
  auth: [appSession, localDev()],
});

Replace the example issuer with a stable identifier for your identity system. Keep principalId stable for each user; when accepting multiple identity providers, use the verified provider's issuer to distinguish their identities. Never take the user ID directly from unverified headers or request JSON.

The example accepts application sessions and local development callers. If the agent also needs Edgenivo service callers, add vercelOidc() between appSession and localDev().

For a frontend on the same origin, browser requests can carry the application session cookie. Your agent's verifier must validate that cookie. If your application uses bearer tokens, send the token in the Authorization header and verify it in the authenticator.

Route authentication does not enforce session ownership. If multiple users or tenants can reach the agent, your application must also enforce which sessions each caller may read or modify. A successful authentication result alone does not establish permission to access a particular session.

When auth is an array, eve evaluates its entries in order:

  • Returning an authentication context accepts the caller and stops evaluation.
  • Returning null or undefined lets the next authenticator try.
  • Throwing rejects the request.

If no authenticator accepts the caller, the request receives 401. Put application-specific verifiers first and localDev() last.

User-scoped Connect credentials require principalType: 'user'. The browser example supplies this from a verified application session. Built-in platform channels such as Slack derive a user principal from the sender.

A local development, service, or anonymous identity doesn't satisfy this requirement. If a user-scoped connection fails with principal_required, authenticate an actual user before requesting the token. Use app-scoped authorization only when the external service should act as the agent itself.

Follow Authorize an MCP connection to configure the outbound connection after establishing the caller's identity.

SymptomWhat to check
The browser receives a response saying authentication isn't configuredReplace placeholderAuth() with a verifier for the browser's credentials.
Requests work locally but receive 401 after deploymentlocalDev() doesn't authenticate production traffic. Check the deployed authenticator and its environment variables.
The health endpoint succeeds but session requests failHealth bypasses channel authentication. Test an authenticated session request separately.
A user-scoped connection reports principal_requiredEnsure the channel returns a verified user principal, not only a service or development identity.
Deployment Protection prevents a request from reaching eveConfigure access through Deployment Protection. Its bypass is separate from eve authentication.

Was this helpful?

supported.