Skip to content

Users and API Keys

hitchhiker edited this page Feb 4, 2026 · 4 revisions

Users, Groups, and API Keys

Fold uses OIDC authentication for user management and API tokens for programmatic access. This guide covers user registration, group management, API key generation, and chunking strategies for large codebases.


Authentication Overview

Fold supports two authentication methods:

Session-Based (Web UI)

  • Browser-based login via OIDC providers
  • Session cookies with httpOnly and secure flags
  • Automatic expiry

Token-Based (API and MCP)

  • API tokens generated by authenticated users
  • Bearer token authentication
  • Project-scoped access control

OIDC Configuration

Fold integrates with OIDC providers for authentication. Configure providers through environment variables or the web UI.

Supported Providers

Provider Configuration
Google OIDC_GOOGLE_CLIENT_ID, OIDC_GOOGLE_CLIENT_SECRET
GitHub OIDC_GITHUB_CLIENT_ID, OIDC_GITHUB_CLIENT_SECRET
Zitadel OIDC_ZITADEL_URL, OIDC_ZITADEL_CLIENT_ID, OIDC_ZITADEL_CLIENT_SECRET
Custom OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET

Environment Variables

# Google OAuth
OIDC_GOOGLE_CLIENT_ID=your-google-client-id
OIDC_GOOGLE_CLIENT_SECRET=your-google-client-secret

# GitHub OAuth
OIDC_GITHUB_CLIENT_ID=your-github-client-id
OIDC_GITHUB_CLIENT_SECRET=your-github-client-secret

# Zitadel
OIDC_ZITADEL_URL=https://zitadel.example.com
OIDC_ZITADEL_CLIENT_ID=your-client-id
OIDC_ZITADEL_CLIENT_SECRET=your-client-secret

# Callback URL (must match provider configuration)
OIDC_REDIRECT_URI=https://fold.example.com/auth/callback

OIDC Scopes

Fold requests the following scopes by default:

  • openid — Get a unique identifier
  • profile — Display name and avatar
  • email — User email address

User Management

Login Flow

User visits /auth/login/:provider
       │
       ▼
Redirects to OIDC provider
       │
       ▼
User enters credentials
       │
       ▼
Provider redirects back to /auth/callback
       │
       ▼
Fold creates/updates user record
       │
       ▼
Session created, user logged in

API Endpoints

Get Current User

GET /auth/me
Authorization: Bearer token or Cookie: session=...

Response:
{
  "id": "user_abc123",
  "provider": "google",
  "email": "user@example.com",
  "display_name": "John Doe",
  "avatar_url": "https://...",
  "created_at": "2026-02-03T10:00:00Z"
}

Login with Provider

GET /auth/login/:provider

Redirects to OIDC provider login page.
Supported providers: google, github, zitadel, custom

Logout

POST /auth/logout
Authorization: Bearer token or Cookie: session=...

Invalidates session/token and logs out user.

Groups and Access Control

Fold uses project-based access control. Users and groups are assigned to projects with roles (member or viewer). Access is managed through project membership; tokens inherit the user's access.

Access Model

By User: Users access projects based on their membership (direct or via groups).

By Token: API tokens inherit the user's project access. They cannot be further scoped to restrict access.

Access is controlled through:

  • Direct membership (project_members table) — user to project
  • Group membership (group_members table + project_group_members table) — user to group to project
  • Roles — member (read/write) or viewer (read-only) per project

Groups Support

Groups are implemented:

  • Organise users into groups (groups table)
  • Assign group access to projects with roles (project_group_members table)
  • Users inherit group permissions automatically

API Keys and Tokens

Creating an API Token

Via API

curl -X POST https://fold.example.com/me/tokens \
  -H "Authorization: Bearer <session_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CI Pipeline"
  }'

Response: 201 Created

{
  "id": "tok_abc123",
  "name": "CI Pipeline",
  "token": "fold_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "created_at": "2026-02-03T10:00:00Z"
}

The token is only returned once. Store it securely (environment variable, secret manager).

The token inherits all project access from the user who created it. No project scoping is possible at token creation time.

Using an API Token

Include the token in the Authorization header:

curl -H "Authorization: Bearer fold_xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  https://fold.example.com/api/projects

Or in MCP configuration:

claude mcp add -t http -s user fold http://localhost:8765/mcp \
  --header "Authorization: Bearer fold_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Listing Tokens

curl -H "Authorization: Bearer <token>" \
  https://fold.example.com/me/tokens

Response:

{
  "tokens": [
    {
      "id": "tok_abc123",
      "name": "CI Pipeline",
      "created_at": "2026-02-03T10:00:00Z",
      "last_used": "2026-02-04T15:30:00Z"
    }
  ]
}

Revoking a Token

curl -X DELETE https://fold.example.com/me/tokens/tok_abc123 \
  -H "Authorization: Bearer <token>"

Token Security

Best Practices:

  • Store tokens in environment variables or secrets manager
  • Never commit tokens to git
  • Rotate tokens regularly
  • Revoke unused tokens
  • Use short-lived tokens for CI/CD where possible
  • Control token access via project membership (direct user or group membership)
  • Revoke tokens for users who leave the team

Token Format

fold_<16-char-random>

Tokens are hashed with SHA256 in the database. Only the full token is shown once at creation.


Chunking Technology During Indexing

When indexing large files, Fold uses intelligent chunking to break content into manageable pieces for analysis and embedding.

Chunking Strategy

Single-Memory Model

Despite chunking during analysis, Fold creates one memory per file, not per chunk. Chunks are used for:

  • LLM analysis (summarisation, metadata extraction)
  • Embedding generation (semantic search)
  • Context reconstruction

The full file content is stored in fold/a/b/hash.md.

Chunking Configuration

# Maximum file size (skip larger files)
MAX_FILE_SIZE=100KB              # Default: 100KB

# Chunk size for analysis
CHUNK_SIZE=8KB                   # Default: 8KB

# Chunk overlap (for context)
CHUNK_OVERLAP=1KB                # Default: 1KB

Chunking Process

Large File (src/service.ts)
       │
       ▼
Split into chunks (8KB each with 1KB overlap)
       │
    ┌──┴──────────────────────────┐
    ▼                              ▼
Chunk 1                        Chunk 2
"export class Service..."      "...public method..."
       │                            │
       ▼                            ▼
LLM analyses each chunk      LLM analyses chunk
       │                            │
    ┌──┴────────────────────────────┘
    │
    ▼
Combine insights into single summary
    │
    ▼
Create memory with full file content + metadata

Chunk Types

Code Chunks

Split on:

  • Function/class definitions
  • Logical blocks
  • Line boundaries (max 8KB)

Documentation Chunks

Split on:

  • Sections (markdown headers)
  • Paragraphs
  • Line boundaries

Mixed Chunks

For files with code and docs, split intelligently based on content type.

Overlap Benefits

Chunks overlap by 1KB to preserve context:

Chunk 1: [lines 1-200] + overlap (last 15 lines)
Chunk 2: [overlap (first 15 lines) + lines 200-400] + overlap
Chunk 3: [overlap (first 15 lines) + lines 400-600]

This ensures the LLM doesn't miss relationships at chunk boundaries.

Processing Large Files

File Too Large (>100KB)

  • Skipped during indexing
  • Logged with reason
  • Can be manually chunked by user

Workaround

For large generated files (e.g. bundled CSS):

  1. Exclude from indexing: exclude = ["dist/**", "*.min.js"]
  2. Or manually split into logical chunks using file structure

Session Management

Session Configuration

# Session secret (used for signing cookies)
SESSION_SECRET=your-random-secret-key

# Session lifetime
SESSION_TIMEOUT=24h              # Default: 24 hours

# Cookie settings
COOKIE_DOMAIN=fold.example.com   # Optional domain restriction
COOKIE_PATH=/                    # Default: root

Session Security

  • httpOnly: Prevents JavaScript access
  • Secure: Only sent over HTTPS in production
  • SameSite: Strict (prevents CSRF)
  • Expiry: Configurable timeout

Rotating Sessions

Sessions are automatically rotated:

  • On login
  • After specified timeout
  • On privilege changes

API Token Lifecycle

Creating Tokens

  1. User logs in via OIDC
  2. User creates API token via /me/tokens endpoint
  3. Token is generated and hashed
  4. Token returned once (show to user to copy)

Using Tokens

  1. Token included in Authorization: Bearer header
  2. Server validates token against database
  3. Permission check: user who owns token must have access to the project
  4. Operation proceeds with token's user context and project membership

Expiring Tokens

Tokens do not expire automatically. Users must revoke manually:

curl -X DELETE https://fold.example.com/me/tokens/:id \
  -H "Authorization: Bearer <token>"

Token Auditing

Future feature: Log all token usage for security auditing.


Common Workflows

Enable CI/CD Access

# 1. Create a service account user (or use existing user)
# User must have access to the project(s) being indexed

# 2. Create API token for the service account
curl -X POST https://fold.example.com/me/tokens \
  -H "Authorization: Bearer <session>" \
  -d '{
    "name": "GitHub Actions"
  }'

# 3. Copy token and add to GitHub secrets
# Settings → Secrets → New repository secret
# FOLD_API_TOKEN = fold_xxxx...

# 4. Use in workflow
- name: Index codebase
  env:
    FOLD_API_TOKEN: ${{ secrets.FOLD_API_TOKEN }}
  run: |
    claude mcp add -t http -s user fold http://fold:8765/mcp \
      --header "Authorization: Bearer $FOLD_API_TOKEN"

Token will have access to all projects that the service account user has access to. To limit access, adjust the service account's project membership instead.

Grant Access to Team Member

  1. Team member logs in via Google/GitHub/Zitadel
  2. Admin creates project
  3. Admin shares project slug with team member
  4. Team member can access project after login

Revoke Access

  1. Remove user from project membership (direct or group)
  2. Or delete API token: DELETE /me/tokens/:id
  3. Or disable OIDC provider in user's identity provider

Troubleshooting

"Invalid token"

  • Token is malformed or expired
  • Verify token format starts with fold_
  • Check token hasn't been revoked

"Forbidden" (403)

  • User doesn't have access to the project
  • Check project membership (direct or group)
  • Ensure user has at least viewer role on the project

"Provider not configured"

  • OIDC provider environment variables not set
  • Check OIDC_* variables in .env

"Session expired"

  • Session timeout reached (default 24 hours)
  • Log in again to create new session

Next Steps

See Configuration for OIDC provider setup details and API-Reference for endpoint documentation.

Clone this wiki locally