Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,078 changes: 1,073 additions & 5 deletions apps/framework-docs-v2/content/moosestack/apis/analytics-api.mdx

Large diffs are not rendered by default.

273 changes: 268 additions & 5 deletions apps/framework-docs-v2/content/moosestack/apis/auth.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,272 @@
---
title: Auth
description: Authentication for APIs
order: 1
title: API Authentication & Security
description: Secure your Moose API endpoints with JWT tokens or API keys
order: 3
category: apis
---

# Auth
import { Callout } from "@/components/mdx";

This page is a placeholder. Content migration pending.
# API Authentication & Security

Moose supports two authentication mechanisms for securing your API endpoints:

- **[API Keys](#api-key-authentication)** - Simple, static authentication for internal applications and getting started
- **[JWT (JSON Web Tokens)](#jwt-authentication)** - Token-based authentication for integration with existing identity providers

Choose the method that fits your use case, or use both together with custom configuration.

## Do you want to use API Keys?

API keys are the simplest way to secure your Moose endpoints. They're ideal for:
- Internal applications and microservices
- Getting started quickly with authentication
- Scenarios where you control both client and server

### How API Keys Work

API keys use PBKDF2 HMAC SHA256 hashing for secure storage. You generate a token pair (plain-text and hashed) using the Moose CLI, store the hashed version in environment variables, and send the plain-text version in your request headers.

### Step 1: Generate API Keys

Generate tokens and hashed keys using the Moose CLI:

```bash
moose generate hash-token
```

**Output:**
- **ENV API Keys**: Hashed key for environment variables (use this in your server configuration)
- **Bearer Token**: Plain-text token for client applications (use this in `Authorization` headers)

<Callout type="info">
Use the **hashed key** for environment variables and `moose.config.toml`. Use the **plain-text token** in your `Authorization: Bearer token` headers.
</Callout>

### Step 2: Configure API Keys with Environment Variables

Set environment variables with the **hashed** API keys you generated:
```bash
# For ingest endpoints
export MOOSE_INGEST_API_KEY='your_pbkdf2_hmac_sha256_hashed_key'

# For analytics endpoints
export MOOSE_CONSUMPTION_API_KEY='your_pbkdf2_hmac_sha256_hashed_key'

# For admin endpoints
export MOOSE_ADMIN_TOKEN='your_plain_text_token'
```

Or set the admin API key in `moose.config.toml`:

```toml filename="moose.config.toml"
[authentication]
admin_api_key = "your_pbkdf2_hmac_sha256_hashed_key"
```

<Callout type="info" title="Storing Admin API Keys in Project Configuration File">
Storing the `admin_api_key` (which is a PBKDF2 HMAC SHA256 hash) in your `moose.config.toml` file is an acceptable practice, even if the file is version-controlled. This is because the actual plain-text Bearer token (the secret) is not stored. The hash is computationally expensive to reverse, ensuring that your secret is not exposed in the codebase.
</Callout>

### Step 3: Make Authenticated Requests

All authenticated requests require the `Authorization` header with the **plain-text token**:

```bash
# Using curl
curl -H "Authorization: Bearer your_plain_text_token_here" \
https://your-moose-instance.com/ingest/YourDataModel

# Using JavaScript
fetch('https://your-moose-instance.com/api/endpoint', {
headers: {
'Authorization': 'Bearer your_plain_text_token_here'
}
})
```

## Do you want to use JWTs?

JWT authentication integrates with existing identity providers and follows standard token-based authentication patterns. Use JWTs when:
- You have an existing identity provider (Auth0, Okta, etc.)
- You need user-specific authentication and authorization
- You want standard OAuth 2.0 / OpenID Connect flows

### How JWT Works

Moose validates JWT tokens using RS256 algorithm with your identity provider's public key. You configure the expected issuer and audience, and Moose handles token verification automatically.

### Step 1: Configure JWT Settings

#### Option A: Configure in `moose.config.toml`

```toml filename=moose.config.toml
[jwt]
# Your JWT public key (PEM-formatted RSA public key)
secret = """
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy...
-----END PUBLIC KEY-----
"""
# Expected JWT issuer
issuer = "https://my-auth-server.com/"
# Expected JWT audience
audience = "my-moose-app"
```

<Callout type="info">
The `secret` field should contain your JWT **public key** used to verify signatures using RS256 algorithm.
</Callout>

#### Option B: Configure with Environment Variables

You can also set these values as environment variables:

```bash filename=".env" copy
MOOSE_JWT_PUBLIC_KEY=your_jwt_public_key # PEM-formatted RSA public key (overrides `secret` in `moose.config.toml`)
MOOSE_JWT_ISSUER=your_jwt_issuer # Expected JWT issuer (overrides `issuer` in `moose.config.toml`)
MOOSE_JWT_AUDIENCE=your_jwt_audience # Expected JWT audience (overrides `audience` in `moose.config.toml`)
```

### Step 2: Make Authenticated Requests

Send requests with the JWT token in the `Authorization` header:

```bash
# Using curl
curl -H "Authorization: Bearer your_jwt_token_here" \
https://your-moose-instance.com/ingest/YourDataModel

# Using JavaScript
fetch('https://your-moose-instance.com/api/endpoint', {
headers: {
'Authorization': 'Bearer your_jwt_token_here'
}
})
```

## Want to use both? Here's the caveats

You can configure both JWT and API Key authentication simultaneously. When both are configured, Moose's authentication behavior depends on the `enforce_on_all_*` flags.

### Understanding Authentication Priority

#### Default Behavior (No Enforcement)

By default, when both JWT and API Keys are configured, Moose tries JWT validation first, then falls back to API Key validation:

```toml filename="moose.config.toml"
[jwt]
# JWT configuration
secret = "..."
issuer = "https://my-auth-server.com/"
audience = "my-moose-app"
# enforce flags default to false
```

```bash filename=".env"
# API Key configuration
MOOSE_INGEST_API_KEY='your_pbkdf2_hmac_sha256_hashed_key'
MOOSE_CONSUMPTION_API_KEY='your_pbkdf2_hmac_sha256_hashed_key'
```

**For Ingest Endpoints (`/ingest/*`)**:
- Attempts JWT validation first (RS256 signature check)
- Falls back to API Key validation (PBKDF2 HMAC SHA256) if JWT fails

**For Analytics Endpoints (`/api/*`)**:
- Same fallback behavior as ingest endpoints

This allows you to use either authentication method for your clients.

#### Enforcing JWT Only

If you want to **only** accept JWT tokens (no API key fallback), set the enforcement flags:

```toml filename="moose.config.toml"
[jwt]
secret = "..."
issuer = "https://my-auth-server.com/"
audience = "my-moose-app"
# Only accept JWT, no API key fallback
enforce_on_all_ingest_apis = true
enforce_on_all_consumptions_apis = true
```

**Result**: When enforcement is enabled, API Key authentication is disabled even if the environment variables are set. Only valid JWT tokens will be accepted.

### Common Use Cases

#### Use Case 1: Different Auth for Different Endpoints

Configure JWT for user-facing analytics endpoints, API keys for internal ingestion:

```toml filename="moose.config.toml"
[jwt]
secret = "..."
issuer = "https://my-auth-server.com/"
audience = "my-moose-app"
enforce_on_all_consumptions_apis = true # JWT only for /api/*
enforce_on_all_ingest_apis = false # Allow fallback for /ingest/*
```

```bash filename=".env"
MOOSE_INGEST_API_KEY='hashed_key_for_internal_services'
```

#### Use Case 2: Migration from API Keys to JWT

Start with both configured, no enforcement. Gradually migrate clients to JWT. Once complete, enable enforcement:

```toml filename="moose.config.toml"
[jwt]
secret = "..."
issuer = "https://my-auth-server.com/"
audience = "my-moose-app"
# Start with both allowed during migration
enforce_on_all_ingest_apis = false
enforce_on_all_consumptions_apis = false
# Later, enable to complete migration
# enforce_on_all_ingest_apis = true
# enforce_on_all_consumptions_apis = true
```

### Admin Endpoints

Admin endpoints use API key authentication exclusively (configured separately from ingest/analytics endpoints).

**Configuration precedence** (highest to lowest):
1. `--token` CLI parameter (plain-text token)
2. `MOOSE_ADMIN_TOKEN` environment variable (plain-text token)
3. `admin_api_key` in `moose.config.toml` (hashed token)

**Example:**

```bash
# Option 1: CLI parameter
moose remote plan --token your_plain_text_token

# Option 2: Environment variable
export MOOSE_ADMIN_TOKEN='your_plain_text_token'
moose remote plan

# Option 3: Config file
# In moose.config.toml:
# [authentication]
# admin_api_key = "your_pbkdf2_hmac_sha256_hashed_key"
```

## Security Best Practices

- **Never commit plain-text tokens to version control** - Always use hashed keys in configuration files
- **Use environment variables for production** - Keep secrets out of your codebase
- **Generate unique tokens for different environments** - Separate development, staging, and production credentials
- **Rotate tokens regularly** - Especially for long-running production deployments
- **Choose the right method for your use case**:
- Use **API Keys** for internal services and getting started
- Use **JWT** when integrating with identity providers or need user-level auth
- **Store hashed keys safely** - The PBKDF2 HMAC SHA256 hash in `moose.config.toml` is safe to version control, but the plain-text token should only exist in secure environment variables or secret management systems

<Callout type="warning">
Never commit plain-text tokens to version control. Use hashed keys in configuration files and environment variables for production.
</Callout>
Loading
Loading