How to Use the Authentication Skill in Agent-Native: Configuration and Implementation Guide

The authentication skill in Agent-Native wraps Better Auth to provide secure, unified session management for both browser users and programmatic MCP clients, exposing a standard AuthSession interface accessible via useSession() in React components and getSession() in server routes.

Agent-Native is an open-source framework from BuilderIO that ships with a dedicated authentication skill designed to handle identity across multiple contexts. This skill eliminates the need to manually integrate authentication libraries by providing a pre-configured Better Auth wrapper that supports email/password, social providers, and custom third-party authentication systems.

How the Authentication Skill is Wired Into the App

The authentication system initializes automatically when the Nitro server boots. The core server package exports createAuthPlugin and the shortcut autoMountAuth from packages/core/src/server/index.ts, which the generated server imports as its first initialization step.

// packages/core/src/server/index.ts
export { createAuthPlugin, defaultAuthPlugin } from "./auth-plugin.js";

When the server starts, the plugin mounts Better Auth routes under /_agent-native/auth/ba/* and maintains legacy compatibility endpoints at /session, /login, /register, and /logout. This automatic mounting happens without requiring manual route registration in your application code.

Authentication Modes

The skill supports three distinct authentication strategies that all resolve to the same AuthSession object:

  • Default (Better Auth): Email and password authentication with optional social providers (Google, GitHub). This mode displays an onboarding page on first visit and stores sessions via HTTP-only cookies.
  • Remote MCP OAuth: OAuth 2.1 with PKCE for MCP-enabled hosts like Claude Code. Clients receive a WWW-Authenticate challenge from the MCP endpoint and complete the flow without prior tokens.
  • Custom (getSession): Bring-your-own-auth integration that accepts a custom callback to verify sessions from Clerk, Auth0, Firebase, or any other provider.

All three modes normalize identity data into a single AuthSession structure that downstream code can use for authorization decisions.

Session Shape and Types

Every authentication method returns a standardized session object defined in the documentation. The interface lives in packages/core/docs/content/authentication.mdx and includes organization-scoping fields for multi-tenant applications.

interface AuthSession {
  email: string;          // primary identifier
  userId?: string;        // Better Auth user ID
  token?: string;         // session JWT
  name?: string;          // display name from the provider
  image?: string;         // profile picture URL
  orgId?: string;         // active organization ID
  orgRole?: string;       // role within the active org
}

The orgId and orgRole fields enable built-in multi-tenant authorization without requiring separate database queries.

Accessing the Session in the UI

Client-side components consume session data through the useSession hook exported from @agent-native/core/client. This hook subscribes to server-side session changes via the framework's real-time sync layer and automatically re-renders when authentication state changes.

import { useSession } from "@agent-native/core/client";

export function MyComponent() {
  const { session, isLoading } = useSession();

  if (isLoading) return <p>Loading…</p>;
  if (!session) return <p>Not signed in</p>;

  return <p>Hello, {session.email}</p>;
}

The hook handles loading states and null sessions consistently across the application, eliminating the need for manual fetch logic or context providers.

Server-Side Session Access

Server routes and API handlers use getSession imported from @agent-native/core/server to verify identity on the backend. This function parses the session cookie from the incoming request event and returns the validated AuthSession object or null.

import { getSession } from "@agent-native/core/server";

export default defineEventHandler(async (event) => {
  const sess = await getSession(event);
  return { user: sess?.email ?? null };
});

According to the implementation in packages/core/src/server/auth.ts, this helper manages cookie parsing, token verification, and caching to minimize repeated validation overhead.

Sign-In Flow with Return URLs

Public pages that require authentication can redirect users to the standardized sign-in endpoint while preserving the current location. The skill provides /_agent-native/sign-in with a return query parameter that validates same-origin paths to prevent open-redirect vulnerabilities.

import { Button } from "@/components/ui/button";

function SignInCta() {
  const onClick = () => {
    const ret = window.location.pathname + window.location.search;
    window.location.href = `/_agent-native/sign-in?return=${encodeURIComponent(ret)}`;
  };
  
  return <Button onClick={onClick}>Sign in</Button>;
}

After successful authentication, the user returns automatically to the original page.

Agent-Native automatically scopes session cookies based on the deployment configuration to ensure security across different hosting patterns:

Deployment Shape Cookie Realm Behavior
Standalone app an_<slug> (stable in production)
Workspace mode (AGENT_NATIVE_WORKSPACE=1) Shared across all workspace apps
Same-database subdomains Shared when COOKIE_DOMAIN environment variable is set
First-party hosted (*.agent-native.com) Isolated per app by default

This isolation prevents session leakage between applications while allowing intentional sharing in workspace or subdomain scenarios.

Environment Variables for Configuration

The authentication skill recognizes several environment variables defined in packages/core/docs/content/authentication.mdx that control behavior without code changes:

  • BETTER_AUTH_SECRET: Signing key for Better Auth (auto-generated if omitted)
  • AUTH_SKIP_EMAIL_VERIFICATION: Set to 1 to disable verification in QA/preview environments
  • AUTH_DISABLED: Set to true to run every request as a shared user (development only)
  • COOKIE_DOMAIN: Enables shared cookies across subdomains
  • GOOGLE_SIGN_IN_CLIENT_ID / GOOGLE_SIGN_IN_CLIENT_SECRET: Primary Google OAuth credentials
  • GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET: GitHub OAuth credentials
  • ACCESS_TOKEN / ACCESS_TOKENS: Static bearer tokens for MCP client authentication

Social provider credentials automatically enable the corresponding login buttons in the default Better Auth UI.

Custom Authentication (Bring Your Own Auth)

To replace Better Auth with a custom provider, export a plugin that supplies a getSession callback. The implementation in packages/core/src/server/auth-plugin.ts accepts this callback and integrates it into the request lifecycle.

// server/plugins/auth.ts
import { createAuthPlugin } from "@agent-native/core/server";

export default createAuthPlugin({
  getSession: async (event) => {
    const session = await myAuthProvider.verify(event);
    if (!session) return null;
    return { email: session.email };
  },
  publicPaths: ["/api/webhooks"],   // optional: routes that bypass auth
});

This pattern allows gradual migration from existing auth systems or integration with enterprise identity providers while retaining Agent-Native's session interface.

Typical Template Usage

Every generated template includes a server/plugins/auth.ts file that re-exports createAuthPlugin with default options. This file serves as the extension point for per-application customization.

// templates/mail/server/plugins/auth.ts
import { createAuthPlugin } from "@agent-native/core/server";

export default createAuthPlugin({});

As implemented in the template files, this structure makes it trivial to customize authentication logic without modifying core framework code.

Summary

  • The authentication skill mounts automatically via createAuthPlugin in packages/core/src/server/index.ts, handling routes under /_agent-native/auth/ba/*.
  • Three authentication modes (Better Auth, MCP OAuth, custom getSession) all resolve to a standard AuthSession interface with email, userId, and organization fields.
  • Use useSession() in React components and getSession(event) in server handlers to access identity data.
  • Configure social providers and security settings via environment variables like GOOGLE_SIGN_IN_CLIENT_ID and COOKIE_DOMAIN.
  • Implement custom authentication by providing a getSession callback to createAuthPlugin in server/plugins/auth.ts.

Frequently Asked Questions

How do I access the current user session in a React component?

Import useSession from @agent-native/core/client and call it inside your component. The hook returns { session, isLoading } where session contains the AuthSession object with the user's email, name, and organization details, or null if unauthenticated. This hook automatically subscribes to real-time session updates.

Can I use a custom authentication provider instead of Better Auth?

Yes. Create a file at server/plugins/auth.ts that imports createAuthPlugin from @agent-native/core/server and export the result with a custom getSession callback. This callback receives the request event and should return an AuthSession object or null, allowing integration with Clerk, Auth0, Firebase, or any other provider.

What environment variables are required to enable Google or GitHub login?

Set GOOGLE_SIGN_IN_CLIENT_ID and GOOGLE_SIGN_IN_CLIENT_SECRET for Google authentication, or GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET for GitHub. These credentials automatically enable the corresponding social login buttons in the default authentication UI. You should also set BETTER_AUTH_SECRET in production to ensure secure session signing.

How does session isolation work across subdomains or workspaces?

Agent-Native automatically scopes cookies based on your deployment configuration. Standalone apps use an isolated cookie (an_<slug>), while enabling AGENT_NATIVE_WORKSPACE=1 creates a shared session across workspace apps. For same-database subdomains, set the COOKIE_DOMAIN environment variable to enable shared authentication across your domain.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →