Skip to main content

Organization Auth

Introduction

Organization-scoped authentication enables server-side requests authenticated at the organization level rather than the user level. This authentication method is essential for operations that require authentication but cannot use user-scoped auth (typically when users are unauthenticated or don't have accounts yet).

Unlike user-scoped authentication which uses individual user credentials, organization-scoped auth uses a shared organization access token to perform operations on behalf of the organization. This prevents sensitive data from being publicly accessible while still allowing necessary operations for unauthenticated users.

Key Characteristics
  • Server-side only: Strictly for SSR, API handlers, and Server Actions. Never exposed client-side
  • Cached tokens: Encrypted tokens stored in Vercel Edge Config for high performance
  • Automatic refresh: Automatic token refresh cron job using a cron job
  • Fallback mechanism: Direct API calls if cached tokens are invalid

Getting started

Before you begin

This is an advanced authentication feature. Complete the Getting Started: Pages Router or Getting Started: App Router guide first.

Configuration

Organization-scoped authentication requires additional configuration beyond basic auth setup, including Vercel Edge Config integration and token encryption.

Edge Config setup

See Vercel's Edge Config documentation for setup instructions.

Environment variables

Add these environment variables to your .env.local file and configure them in your Vercel project settings:

.env.local
# Organization authentication (Kraken > API Tools > API organisations)
KRAKEN_ORGANIZATION_KEY="your-organization-secret-key"

# Vercel Edge Config (automatically configured by Vercel)
EDGE_CONFIG="https://edge-config.vercel.com/..."
# Vercel API access token (create at https://vercel.com/account/tokens)
VERCEL_AUTH_TOKEN="your-edge-config-access-token"
# Vercel team ID
VERCEL_TEAM_ID="your-vercel-team-id"

# Token encryption (key hashed to 256-bit, IV should be 12+ bytes)
AUTH_ENCRYPTION_KEY="your-encryption-key"
AUTH_ENCRYPTION_IV="your-encryption-iv"

# Cron job authentication (16 characters minimum)
CRON_SECRET="your-cron-secret"
Generating encryption keys

Generate strong random values for encryption keys and secrets:

# Encryption key
openssl rand -base64 32

# Initialization vector
openssl rand -base64 16

# Cron secret
openssl rand -base64 16

Treat these values as sensitive credentials and never commit them to version control.

Auth configuration

Automatic environment variable detection

createAuthConfig automatically picks up the Edge Config, encryption, and Kraken configuration from environment variables. As long as the environment variables are set correctly, organization-scoped auth will work without additional config changes.

Server functions

You can use getOrganizationScopedGraphQLClient either directly from the package or using a factory function:

Export the function from your server auth utilities using the factory:

lib/auth/server.ts
import { createServerSideAuth } from "@krakentech/blueprint-auth/server";
import { authConfig } from "./config";

export const { getOrganizationScopedGraphQLClient } =
createServerSideAuth(authConfig);

Token refresh cron job

Organization tokens expire after 60 minutes. Set up a cron job to refresh tokens every 55 minutes to ensure they remain valid.

API handler

pages/api/auth/update-org-token.ts
import { createUpdateOrgTokenHandler } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

export default createUpdateOrgTokenHandler(authConfig);

Vercel cron configuration

Create or update vercel.json at the root of your project:

vercel.json
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"crons": [
{
"path": "/api/auth/update-org-token",
"schedule": "*/55 * * * *"
}
]
}
Cron schedule

The */55 * * * * schedule runs every 55 minutes. Since organization tokens typically expire after 60 minutes, this provides a 5-minute buffer to ensure tokens are always valid.

Cron secret required

The cron job handler validates requests using the CRON_SECRET environment variable. Vercel automatically includes this secret in cron job requests. Ensure CRON_SECRET is set in your environment variables.

Usage

Server-side only

Organization-scoped authentication is for server-side use only.

Queries

Use organization-scoped auth when fetching data that isn't publicly accessible for unauthenticated users.

pages/signup/products.tsx
import type {
GetServerSidePropsContext,
InferGetServerSidePropsType,
} from "next";
import { getOrganizationScopedGraphQLClient } from "@/lib/auth/server";
import { graphql } from "@/lib/graphql";
import { ProductCard } from "@/components/ProductCard";

export default function ProductsPage({
products,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
return (
<div>
<h1>Products</h1>
{products.map((product) => (
<ProductCard key={product.code} product={product} />
))}
</div>
);
}

const ProductsQuery = graphql(`
query SignupProducts() {
products(availability: AVAILABLE) {
code
fullName
description
tariffs {
id
standingCharge
unitRate
}
}
}
`);

export async function getServerSideProps(context: GetServerSidePropsContext) {
const graphQLClient = getOrganizationScopedGraphQLClient({
context,
});

const { products } = await graphQLClient.request(ProductsQuery);

if (!products?.length) {
return { notFound: true };
}

return {
props: { products },
};
}

Mutations

Use organization-scoped auth for mutations that create or modify data for users who aren't authenticated yet. A common example is account creation.

pages/api/signup/create-account.ts
import type { NextApiRequest, NextApiResponse } from "next";
import { getOrganizationScopedGraphQLClient } from "@/lib/auth/server";
import { graphql } from "@/lib/graphql";
import { z } from "zod";

const CreateAccountMutation = graphql(`
mutation CreateAccount($input: CreateAccountInput!) {
createAccount(input: $input) {
account {
id
number
}
}
}
`);

const createAccountSchema = z.object({
email: z.string().email(),
// ... other fields
});

export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
if (req.method !== "POST") {
return res.status(405).json({ error: "Method not allowed" });
}

const result = createAccountSchema.safeParse(req.body);
if (!result.success) {
return res.status(400).json({ error: "Invalid request data" });
}

const {
email,
// ... other fields
} = result.data;

try {
// User doesn't have an account yet, use organization-scoped auth
const graphQLClient = getOrganizationScopedGraphQLClient({
context: { req, res },
});

const { createAccount } = await graphQLClient.request(
CreateAccountMutation,
{
input: {
email,
// ... other fields
},
},
);

return res.redirect(
303,
`/dashboard/accounts/${createAccount.account.number}`,
);
} catch (error) {
console.error("Account creation failed:", error);
return res.status(500).json({ error: "Account creation failed" });
}
}

How it works

Token Management Overview

Organization-scoped auth uses a cached token system to provide high performance while maintaining security:

  1. Token Storage: Access tokens are encrypted using AES-256-GCM and stored in Edge Config.
  2. Token Retrieval: getOrganizationScopedGraphQLClient() retrieves cached tokens from Edge Config
  3. Automatic Refresh: If a token is expired or invalid, the client automatically fetches a fresh token
  4. Cron Refresh: A cron job refreshes tokens to ensure a valid token is always available
  5. Edge Config Updates: New tokens are encrypted and written back to Edge Config, with automatic cache invalidation across all edge regions

This architecture ensures sub-millisecond token retrieval in most cases while gracefully handling token expiration and rotation.

Security considerations

Critical Security Requirements
  1. Environment variables: Treat KRAKEN_ORGANIZATION_KEY, AUTH_ENCRYPTION_KEY, AUTH_ENCRYPTION_IV, and CRON_SECRET as highly sensitive credentials
  2. Cron endpoint protection: The token refresh endpoint is protected by CRON_SECRET. Never expose this value
  3. Token encryption: All cached tokens are encrypted before storage in Edge Config
  4. Minimal scope: Organization tokens grant broader permissions than user tokens. Use user-scoped auth whenever possible

FAQ

When should I use organization-scoped vs user-scoped auth?

Use organization-scoped auth when:

  • Users are unauthenticated but need to perform authenticated operations (e.g., account creation, signup flows)
  • Users don't have accounts yet but need access to organization data (e.g., product catalogs, pricing)
  • Operations require organization-level permissions rather than user-level permissions

Use user-scoped auth when:

  • User is authenticated and performing actions on their own account
  • Accessing user-specific data (account details, usage, billing, payment methods)
  • Standard logged-in user workflows (dashboard, settings, account management)
How does token caching work?

Organization tokens are encrypted using AES-256-GCM and stored in Vercel Edge Config, which provides:

  • Global edge caching: Tokens are cached at Vercel's edge locations worldwide for sub-millisecond access
  • Automatic invalidation: When tokens are updated via the cron job, Edge Config automatically invalidates the cache globally
  • High availability: 99.99% uptime SLA with automatic failover
  • Encryption at rest: All data in Edge Config is encrypted, with an additional encryption layer from the auth package

The cron job proactively refreshes tokens every 55 minutes (tokens expire after 60 minutes) to ensure cached tokens remain valid. If a cached token fails during a request, the client automatically fetches a fresh one from the Kraken API and updates the cache.

What happens if the cron job fails?

The authentication system has a robust fallback mechanism:

  1. When a request is made with an expired or invalid cached token, the GraphQL request will fail with an authentication error
  2. The client automatically detects the authentication failure
  3. The client requests a fresh token directly from the Kraken API using the organization secret key
  4. The new token is encrypted and cached in Edge Config for future requests
  5. The original GraphQL request is retried with the fresh token

While this fallback works seamlessly from the user's perspective, it adds latency (additional API round-trip). Monitor your cron job's success rate in Vercel to ensure tokens are refreshed proactively.

Can I use organization-scoped auth in client components?

No. Organization-scoped auth is strictly server-side only. Exposing the organization token to client-side code would be a critical security vulnerability, granting malicious actors organization-level permissions.

Use it only in:

  • Server-Side Rendering (getServerSideProps, getStaticProps in Pages Router)
  • Server Components (App Router)
  • API Route Handlers (pages/api/... in Pages Router, app/.../route.ts in App Router)
  • Server Actions (App Router)

Next steps

Now that you have organization-scoped authentication configured, explore these related guides:

API Reference

Quick reference to relevant functions: