@aura-stack/auth
Framework-agnostic authentication and authorization library for Aura Stack.
Core API Reference
The @aura-stack/auth package provides a framework-agnostic authentication core for TypeScript applications, built on modern standards like OAuth 2.0 and OpenID Connect (future support planned).
It offers secure, type-safe, and composable primitives designed for an exceptional developer experience (DX).
Inspired by Auth.js, this package focuses on clarity, security, and flexibility, providing everything needed to implement authentication and authorization in a clean and extensible way.
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: ["github"],
secret: process.env.AURA_SECRET!,
basePath: "/auth",
cookies: {
prefix: "aura-auth",
},
trustedProxyHeaders: true,
})What you'll learn
Through this api reference documentation you are going to learn and understand from basic to advanced about the createAuth API Reference:
Features
- OAuth 2.0 support — Integrate multiple providers effortlessly.
- Type-safe API — Built entirely in TypeScript with strong type inference.
- Secure sessions — Backed by JOSE (
JWT,JWS, andJWE) for signing and encryption. - Framework agnostic — Works seamlessly with any HTTP framework or runtime.
- Router integration — Compatible with
@aura-stack/routerfor effortless endpoint mounting.
Installation
npm install @aura-stack/authAPI Reference
createAuth(config: AuthConfig)
Creates an authentication instance with handlers for OAuth flows, session management, and CSRF protection.
Parameters
Configuration object for authentication settings.
| Parameter | Type | Description |
|---|---|---|
oauth | (BuiltInOAuthProvider | OAuthProviderCredentials)[] | Array of OAuth provider configurations |
cookies | CookieConfig | Cookie configuration for session management |
secret | string | Secret value used for signing and encrypting JWTs and CSRF tokens. This option overrides the AURA_AUTH_SECRET environment variable |
basePath | /${string} | Base path for the authentication routes; defaults to /auth |
trustedProxyHeaders | boolean | Enables proxy headers when the app is behind a proxy |
oauth
The OAuth providers are the third-party applications which the Aura Auth will sign in. Can be either
- Built-in providers: are the OAuth built-in by aura auth, for example
github
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: ["github"],
})- Custom OAuth configuration implementations: create custom OAuth providers that are not supported natively by Aura Auth; follow the
OAuthProvidertype.
import type { User } from "@aura-stack/auth/types"
interface OAuthProviderConfig<Profile extends object = {}> {
id: string
name: string
authorizeURL: string
accessToken: string
userInfo: string
scope: string
responseType: string
profile?: (profile: Profile) => Promise<User> | User
}
interface OAuthProviderCredentials extends OAuthProviderConfig {
clientId: string
clientSecret: string
}
type OAuthProvider<Profile extends Record<string, unknown> = {}> = OAuthProviderConfig<Profile> & OAuthProviderCredentials
type BuiltInOAuthProvider = "github" | "bitbucket" | "figma" | "discord" | "gitlab" | "spotify" | "x"Properties
| Property | Type | Description |
|---|---|---|
id | string | Unique identifier for the provider |
name | string | Display name of the provider |
authorizeURL | string | OAuth authorization endpoint |
accessToken | string | Token exchange endpoint |
userInfo | string | User information endpoint |
scope | string | OAuth scopes to request |
responseType | code | refresh_token | id_token | OAuth response type (typically 'code') |
clientId | string | OAuth client ID |
clientSecret | string | OAuth client secret |
profile | function | Optional profile transformer |
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: [
{
id: "custom",
name: "Custom Provider",
authorizeURL: "https://custom.com/authorization",
accessToken: "https://custom.com/access_token",
userInfo: "https://api.custom.com/v1/user",
scope: "user:email user:profile",
responseType: "code",
clientId: process.env.CLIENT_ID!,
clientSecret: process.env.CLIENT_SECRET!,
},
],
})cookies
Cookie configuration management for granural per-cookie for all internal cookies used by Aura Auth (e.g., state, redirect_to, code_verifier, sessionToken, and csrfToken) using the overrides object.
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: [],
cookies: {
prefix: "aura-auth",
overrides: {
sessionToken: {
name: "session_token",
attributes: {
priority: "high",
sameSite: "strict",
},
},
},
},
})import type { StandardCookie, SecureCookie, HostCookie } from "@aura-stack/auth/types"
type CookieStrategyAttributes = StandardCookie | SecureCookie | HostCookie
type CookieStoreConfig = Record<CookieName, { name: string; attributes: CookieStrategyAttributes }>
interface CookieConfig {
prefix?: string
overrides?: Partial<CookieStoreConfig>
}prefix
Define the prefix name to be added to all of the cookies used by Aura Auth, by default is aura-stack.
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: [],
cookies: {
prefix: "aura-auth",
},
})overrides
This configuration option overrides the default cookie attributes or cookie name to the cookies used by Aura Auth. The cookies used are: sessionToken, csrfToken, state, codeVerifier, redirectTo, and redirectURI.
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: [],
cookies: {
overrides: {
sessionToken: {},
csrfToken: {},
state: {},
redirectTo: {}
redirectURI: {}
codeVerifier: {}
},
},
})This configuration option is critical, we recommended to the user be caution and be careful with the options passed to the cookies.overrides options to avoid information leak, cookie attacks and more vulnerabilities exposed by the cookies. So Aura Auth is not resposible for any bad cookie configuration and vulnerabilities caused by this option. For detailed information about cookie management read RFC - HTTP State Management Mechanism.
For that reason Aura Auth, provides secure by default, disabling cases which the cookie configuration options is not recommended and bad configured with httpOnly always to true to be unaccessible by JavaScript.
Aura Auth provides granular per-cookie management with a series of cookie attributes to customize cookie behavior. For type safety, an optional strategy field is provided that recommends appropriate attributes for cookie prefixes (__Secure- and __Host-). The supported values are standard, secure, and host, with standard as the default.
Security Warning: Choose the appropriate cookie flag for your environment. Use host or secure in production for maximum
security.
standard
This flag default in development. Standard cookies without security prefix. Can be sent over HTTP and HTTPS.
type StandardCookie = {
strategy: "standard"
secure?: boolean | undefined
maxAge?: number | undefined
expires?: Date | undefined
domain?: string | undefined
path?: string | undefined
httpOnly?: boolean | undefined
partitioned?: boolean | undefined
priority?: "low" | "medium" | "high" | undefined
sameSite?: boolean | "lax" | "strict" | "none" | undefined
}secure
when secure flag is set in a development environment (HTTP) it is disable because secure cookios only can be transmitted in a HTTPS, additionally it adds the __Secure- prefix to the cookies, for more detailed informationa about the prefix read.
type SecureCookie = {
strategy: "secure"
maxAge?: number | undefined
expires?: Date | undefined
domain?: string | undefined
path?: string | undefined
httpOnly?: boolean | undefined
partitioned?: boolean | undefined
priority?: "low" | "medium" | "high" | undefined
sameSite?: boolean | "lax" | "strict" | "none" | undefined
}host
This flag it the most secure, but is less flexible, when host flag is set in a development environment (HTTP) it is disable because secure cookios only can be transmitted in a HTTPS, additionally it adds the __Host- prefix to the cookies, for more detailed informationa about the prefix read.
- Only sent over HTTPS
- Path must be
/ - No Domain attribute (prevents subdomain access)
type HostCookie = {
strategy: "host"
maxAge?: number | undefined
expires?: Date | undefined
httpOnly?: boolean | undefined
partitioned?: boolean | undefined
priority?: "low" | "medium" | "high" | undefined
sameSite?: boolean | "lax" | "strict" | "none" | undefined
}secret
Secret value used to sign and encrypt JWTs for session management and for CSRF token protection. This configuration overrides the AURA_AUTH_SECRET or AUTH_SECRET environment variable which is automatically loaded by Aura Auth. If neither option is configured, Aura Auth will throw an error, as this option is required for session management and CSRF protection.
type Secret = stringbasePath
Base path used for all authentication routes, including /signIn/:oauth, /session, etc. This base path defines where the handlers are located in the framework's backend. By default, it is /auth.
type basePath = `/${string}`trustedProxyHeaders
trustedProxyHeaders is an experimental option that enables proxy headers for scenarios where the application is behind a reverse proxy or load balancer. This configuration consumes X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto headers to determine the original client IP address and protocol. For more details, read Proxy headers.
type TrustedProxyHeaders = booleanBy default, this is false. Enable this option only if you trust the server or reverse proxy. Enabling this on insecure
connections can lead to security vulnerabilities, such as incorrect handling of secure cookies or inaccurate client IPs.
This is an experimental option and may change over time. Monitor the library for updates and possible changes to this configuration option.
Aura Auth reads proxy headers to determine if connection is secure:
| Header | Purpose | Example |
|---|---|---|
X-Forwarded-Proto | Protocol (HTTP/HTTPS) | https |
X-Forwarded-For | Client IP | 203.0.113.45 |
X-Forwarded-Host | Original host | example.com |
Forwarded | RFC 7239 standard | for=203.0.113.45;proto=https |
Returns
| Return | Type | Description |
|---|---|---|
handlers | HTTP handlers (fromcreateRouter) | Route handlers you can mount in your app to expose authentication endpoints (/signIn/:oauth, /callback/:oauth, /session, etc.). Mount at your desired base path (default: /auth). |
jose | JoseInstance | Object that exports JOSE utilities for signing and encrypting JWTs and CSRF tokens. |
handlers
The HTTP handlers are functions that control the logic and flow of the OAuth 2.0 authorization process. Currently, the GET and POST methods are exported. By default, Aura Auth sets the base path to /auth. For configuration details, refer to basePath.
type Handlers = {
GET: (req: Request) => Response | Promise<Response>
POST: (req: Request) => Response | Promise<Response>
}The HTTP handlers should be implemented by any runtime which supports native Response and Request browswer APIs and use the HTTP handlers to oauth management.
The endpoints supported by the handlers are:
GET /auth/signIn/:oauth
Initiates the OAuth authorization flow. where :oauth is the id of the Oauth Provider
GET /auth/callback/:oauth
Handles the OAuth callback after user authorization. where :oauth is the id of the OAuth Provider, is must be equal that the /auth/signIn/:oauth
GET /auth/session
Returns the current user's session. It is created based on the profile function from the OAuthProvider configuration. By default, the User and Session structures are:
export interface User {
sub: string
name?: string
email?: string
image?: string
}
export interface Session {
user: User
expires: string
}The user's session filters out the JWT standard claims (exp, iat, jti, nbf) and only returns the user-facing profile data.
GET /auth/csrfToken
it returns a json which the csrfToken to mitigate CSRF Attacks and used by http methods which could have important operations and logic (POST, PATCH and DELETE). This token is used and required by /auth/signOut endpoint to close the active user session. the response follows the next structure:
{
"csrfToken": "string"
}POST /auth/signOut
It implements CSRF Tokens as security, so, it expects to pass the X-CSRF-TOKEN header and csrfToken cookie to verify the csrfToken passed.
The csrfToken are signed to ensure integrity of the csrfToken and can't be replicated.
new Request("/auth/signOut", {
method: "POST",
headers: {
"X-CSRF-Token": "...",
Cookie: "...",
},
})All routes are relative to your configured base path (default: /auth).
jose
Object that contains JOSE utilities used internally by Aura Auth for signing and encrypting sessions and CSRF tokens. The Jose utilities implement key derivation for security to avoid using the same secret for both signing and encryption. Two salting options are provided:
type JoseInstance = {
decodeJWT: (token: string) => Promise<JWTPayload>
encodeJWT: (payload: JWTPayload) => Promise<string>
signJWS: (payload: JWTPayload) => Promise<string>
verifyJWS: (payload: string, options?: JWTVerifyOptions) => Promise<JWTPayload>
encryptJWE: (payload: string, options?: EncryptOptions) => Promise<string>
decryptJWE: (payload: string, options?: JWTDecryptOptions) => Promise<string>
}AURA_AUTH_SALT: Environment variable used for salting during key derivation. This is the recommended approach as it provides enhanced security.secret: Creates a key hash based on thesecretvalue from the configuration or theAURA_AUTH_SECRETenvironment variable.
The salt value must be deterministic to ensure session and CSRF tokens remain consistent across server executions. Otherwise, key derivation will generate different values, causing unexpected behavior between restarts.
The JOSE utilities are provided for users to manipulate session tokens and CSRF tokens according to their needs.
OAuth Providers
Aura Auth exposes OAuth provider configurations through the /oauth/ entry point. This entry point provides default OAuth provider configurations and profile types (the default object type returned by the userInfo endpoint).
The /oauth entry point provides configuration for each OAuth provider and combines all configurations into the builtInOAuthProviders object.
Types
const builtInOAuthProviders = {
github,
bitbucket,
figma,
discord,
gitlab,
spotify,
x,
}
type BuiltInOAuthProvider = keyof typeof builtInOAuthProvidersExample
import { builtInOAuthProviders, type builtInOAuthProviders } from "@aura-stack/auth/oauth"
import { github, type GitHubProfile } from "@aura-stack/auth/oauth/github"
import { gitlab, type GitLabProfile } from "@aura-stack/auth/oauth/gitlab"
import { discord, type DiscordProfile, type Nameplate } from "@aura-stack/auth/oauth/discord"Environment Variables
Aura Auth required some environment variables to create the OAuth flow and security measures. The environments required are:
AURA_AUTH_SECRET: opaque value used to sign and encrypt user's sessionAURA_AUTH_SALT: Salt value used for key derivation to sign and encrypt JWTs and CSRF tokens.AURA_AUTH_{PROVIDER}_CLIENT_IDAURA_AUTH-{PROVIDER}_CLIENT_SECRET
Aura Auth loads the environment variables that follows the previous patterns.
Example
# Secret
AURA_AUTH_SECRET="secret"
# Salt
AURA_AUTH_SALT="salt"
# GitHub OAuth
AURA_AUTH_GITHUB_CLIENT_ID=Iv1.1234567890abcdef
AURA_AUTH_GITHUB_CLIENT_SECRET=0123456789abcdef...
# Custom Provider
AURA_AUTH_CUSTOM_CLIENT_ID=your_client_id
AURA_AUTH_CUSTOM_CLIENT_SECRET=your_client_secret.env files to version control. Add them to .gitignore.Errors
In the OAuth 2.0 workflow is possible that happens some erros during the workflow, so, Aura Auth follows the responses provided by RFC 6749 which returns the errors via URL or Body json with the error and error_description fields.
OAuth 2.0 and its extensions defines three cases erros during the Authorization, Access Token and Revocation Tokens flow.
All of the OAuth errors follow the next structure:
interface OAuthError<T extends string> {
error: T
error_description?: string
}Example
{
"error": "access_denied",
"error_description": "User denied authorization"
}AuthorizationError
OAuth 2.0 authorization errors as defined in RFC 6749 #4.1.2.1:
type AuthorizationError = OAuthError<
| "invalid_request"
| "unauthorized_client"
| "access_denied"
| "unsupported_response_type"
| "invalid_scope"
| "server_error"
| "temporarily_unavailable"
>AccessTokenError
OAuth 2.0 access token errors as defined in RFC 6749 #5.2:
type AccessTokenError = OAuthError<
"invalid_request" | "invalid_client" | "invalid_grant" | "unauthorized_client" | "unsupported_grant_type" | "invalid_scope"
>TokenRevocationError
OAuth 2.0 token revocation error as defined in RFC 7009 #2.2.1
type TokenRevocationError = OAuthError<"invalid_session_token" | "invalid_csrf_token" | "invalid_redirect_to">ErrorType
type ErrorType = AuthorizationError["error"] | AccessTokenError["error"] | TokenRevocationError["error"]Usage
With GitHub
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: ["github"],
})With Custom Provider
import { createAuth } from "@aura-stack/auth"
import type { OAuthProvider } from "@aura-stack/auth/types"
const provider: OAuthProvider = {
id: "custom",
name: "Custom OAuth",
authorizeURL: "https://oauth.example.com/authorize",
accessToken: "https://oauth.example.com/access_token",
userInfo: "https://oauth.example.com/userinfo",
scope: "profile email",
responseType: "code",
clientId: process.env.AURA_AUTH_CUSTOM_CLIENT_ID!,
clientSecret: process.env.AURA_AUTH_CUSTOM_CLIENT_SECRET!,
profile: (profile) => ({
sub: profile.id,
name: profile.full_name,
email: profile.email_address,
image: profile.avatar_url,
}),
}
export const auth = createAuth({
oauth: [provider],
})With Cookies
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: ["github"],
cookies: {
prefix: "my-app",
overrides: {
sessionToken: {
name: "session_token",
attributes: {
strategy: "host",
partitioned: true,
},
},
csrfToken: {
name: "csrf_token",
attributes: {},
},
},
},
})With secret
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: ["github"],
secret: process.env.SECRET_KEY!,
})With basePath
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: ["github"],
basePath: "/api/v1/auth",
})With trustedProxyHeaders
import { createAuth } from "@aura-stack/auth"
export const auth = createAuth({
oauth: ["github"],
trustedProxyHeaders: true,
})Best Practices
- Use Environment Variables: Always store credentials in environment variables
- HTTPS in Production: Use HTTPS for all authentication endpoints in production
- Secure Cookies: Configure secure cookie options for production
- Error Handling: Implement proper error handling for auth flows
- Session Validation: Always validate sessions on the server side