Authentication & Access Control
Relevant source files
The following files were used as context for generating this wiki page:
Authentication and Access Control in the Recoup API is a multi-layered system designed to support diverse client types, including web frontends, external API consumers, and Model Context Protocol (MCP) tools. The system unifies different authentication methods—primarily API Keys and JWT-based Bearer tokens—into a consistent internal authContext.
This architecture ensures that every request is associated with a validated accountId and, optionally, an orgId (Organization ID). It also provides robust mechanisms for account impersonation (overrides) and cross-account access validation, particularly for organization-level keys that need to manage individual member accounts.
Unified Authentication Flow
The primary entry point for authentication in API routes is the validateAuthContext function. This utility abstracts the complexity of checking different header types and performs initial validation on the provided credentials.
Authentication Mechanisms
The system strictly enforces the use of exactly one authentication header per request.
| Header | Description | Target Clients |
|---|---|---|
x-api-key | A static API key associated with an account or organization. | External scripts, integrations, MCP tools. |
Authorization: Bearer <token> | A JWT (typically from Privy) representing a user session. | Web frontend, authenticated users. |
Sources: [CLAUDE.md:165-175], [lib/auth/validateAuthContext.ts], [lib/auth/__tests__/validateAuthContext.test.ts:40-60]
Context Resolution Logic
The following diagram illustrates how the system resolves a raw request into a validated authentication context.
This flow ensures that no matter the authentication method, the resulting context is subject to the same access control rules.
Sources: [lib/auth/validateAuthContext.ts], [lib/auth/__tests__/validateAuthContext.test.ts:130-150], [AGENTS.md:165-185]
Account & Organization Access Control
The system distinguishes between the authenticated account (the owner of the credentials) and the target account (the account being operated upon).
Account Overrides
Clients can provide an accountId override in the request body or parameters. This is common when an organization manages multiple sub-accounts. The canAccessAccount utility verifies if the currentAccountId has permission to perform actions on the targetAccountId.
- Self-Access: Access is automatically granted if the
currentAccountIdmatches thetargetAccountId. - Organization Access: Organization-level keys or users can access accounts belonging to their organization.
Sources: [lib/auth/validateAuthContext.ts], [lib/organizations/canAccessAccount.ts], [lib/auth/__tests__/validateAuthContext.test.ts:100-125]
Organization Validation
When an organizationId is provided in the context, the system uses validateOrganizationAccess to ensure the resolved accountId is a valid member of that specific organization. This prevents cross-tenant data leakage.
Sources: [lib/auth/validateAuthContext.ts], [lib/organizations/validateOrganizationAccess.ts], [lib/auth/__tests__/validateAuthContext.test.ts:152-175]
MCP Tool Authentication
Model Context Protocol (MCP) tools use a specialized resolution pattern through resolveAccountId. Since AI agents often operate on behalf of users, the tool must verify that the agent is not exceeding the permissions of the authenticated user.
Sources: [CLAUDE.md:195-215], [AGENTS.md:195-215]
Implementation Details
The AuthContext Object
The successful result of authentication is an AuthContext object, used throughout the business logic layer.
// Conceptual structure based on lib/auth/validateAuthContext.ts
{
accountId: string; // The validated target account ID
orgId: string | null; // The validated organization context
authToken: string; // The raw token used for the request
}
Sources: [lib/auth/validateAuthContext.ts], [lib/auth/__tests__/validateAuthContext.test.ts:70-85]
Critical Naming Conventions
The project strictly enforces specific terminology to avoid confusion between different entity types:
- Account: The primary entity (user, artist, workspace, organization).
- Never use "User" or "Entity": Use
account_idexclusively in code and database schemas.
Sources: [CLAUDE.md:115-125], [AGENTS.md:115-125]
Summary of Key Functions
| Function | File | Purpose |
|---|---|---|
validateAuthContext | lib/auth/validateAuthContext.ts | Main validator for API routes; supports API keys and Bearer tokens. |
getApiKeyAccountId | lib/auth/getApiKeyAccountId.ts | Resolves an x-api-key to an accountId. |
getAuthenticatedAccountId | lib/auth/getAuthenticatedAccountId.ts | Resolves a JWT Bearer token to an accountId. |
resolveAccountId | lib/mcp/resolveAccountId.ts | Resolution logic specifically for MCP tool contexts. |
canAccessAccount | lib/organizations/canAccessAccount.ts | Logic to check if account A can manage account B. |
getApiKeyDetails | lib/keys/getApiKeyDetails.ts | Retrieves metadata (like organization association) for an API key. |
Sources: [CLAUDE.md:175-200], [lib/auth/validateAuthContext.ts], [lib/keys/getApiKeyDetails.ts]
Conclusion
Recoup's Authentication & Access Control system provides a secure, unified gateway for all API interactions. By consolidating credential validation into the validateAuthContext utility and enforcing strict account/organization relationship checks via canAccessAccount, the architecture maintains high security standards while supporting the flexible access patterns required for organization-managed artist accounts and AI-driven MCP tools.